2022-11-05 08:58:44 -04:00
///start file generated from microprofile.html
# ifdef MICROPROFILE_EMBED_HTML
const char g_MicroProfileHtml_begin_0 [ ] =
" <!DOCTYPE HTML> \n "
" <html> \n "
" <head> \n "
" <title>MicroProfile Capture</title> \n "
" <style> \n "
" /* about css: http://bit.ly/1eMQ42U */ \n "
" body {margin: 0px;padding: 0px; font: 12px Courier New;background-color:#474747; color:white;overflow:hidden;} \n "
" ul {list-style-type: none;margin: 0;padding: 0;} \n "
" li{display: inline; float:left;border:5px; position:relative;text-align:center;} \n "
" a { \n "
" float:left; \n "
" text-decoration:none; \n "
" display: inline; \n "
" text-align: center; \n "
" padding:5px; \n "
" padding-bottom:0px; \n "
" padding-top:0px; \n "
" color: #FFFFFF; \n "
" background-color: #474747; \n "
" } \n "
" a:hover, a:active{ \n "
" background-color: #000000; \n "
" } \n "
" \n "
" ul ul { \n "
" position:absolute; \n "
" left:0; \n "
" top:100%; \n "
" margin-left:-999em; \n "
" } \n "
" li:hover ul { \n "
" margin-left:0; \n "
" margin-right:0; \n "
" } \n "
" ul li ul{ display:block;float:none;width:100%;} \n "
" ul li ul li{ display:block;float:none;width:100%;} \n "
" li li a{ display:block;float:none;width:100%;text-align:left;} \n "
" #nav li:hover div {margin-left:0;} \n "
" .help {position:absolute;z-index:5;text-align:left;padding:2px;margin-left:-999em;background-color: #313131;width:300px;} \n "
" .helpstart {position:absolute;z-index:5;text-align:left;padding:2px;background-color: #313131;width:300px;display:none} \n "
" .root {z-index:1;position:absolute;top:0px;left:0px;} \n "
" </style> \n "
" </head> \n "
" <body style= \" \" > \n "
" <canvas id= \" History \" height= \" 70 \" style= \" background-color:#474747;margin:0px;padding:0px; \" ></canvas><canvas id= \" DetailedView \" height= \" 200 \" style= \" background-color:#474747;margin:0px;padding:0px; \" ></canvas> \n "
" <div id= \" root \" class= \" root \" > \n "
" <ul id= \" nav \" > \n "
" <li><a href= \" javascript:void(0) \" onclick= \" ToggleDebugMode(); \" >?</a> \n "
" <div class= \" helpstart \" id= \" helpwindow \" style= \" left:20px;top:20px \" > \n "
" History View:<br> \n "
" Click + Drag: Pan View<br> \n "
" Right Click + Drag : Zoom on region<br> \n "
" Click Frame : Center on frame<br> \n "
" <hr> \n "
" Main View:<br> \n "
" Ctrl + Mouse up/down: Zoom<br> \n "
" Mousewheel : Zoom<br> \n "
" Right Click + Drag: Zoom to region<br> \n "
" Ctrl + Drag: Pan<br> \n "
" Click + Drag: Pan<br> \n "
" <hr> \n "
" <table style= \" width:100% \" > \n "
" <tr> \n "
" <td width= \" 50% \" align= \" left \" ><a href= \' javascript:void(0) \' onclick= \" ShowHelp(0, 0); \" >Close</a></td> \n "
" <td width= \" 50% \" align= \" right \" ><a href= \' javascript:void(0) \' onclick= \" ShowHelp(0, 1); \" >Close, Never Show</a></td> \n "
" </tr> \n "
" </table> \n "
" </div> \n "
" <div class= \" help \" id= \" divFrameInfo \" style= \" left:20px;top:300px;width:auto; \" > \n "
" </div> \n "
" </li> \n "
" <li><a id= \' ModeSubMenuText \' >Mode</a> \n "
" <ul id= \' ModeSubMenu \' > \n "
" <li><a href= \" javascript:void(0) \" onclick= \" SetMode( \' timers \' , 0); \" id= \" buttonTimers \" >Timers</a></li> \n "
" <li><a href= \" javascript:void(0) \" onclick= \" SetMode( \' timers \' , 1); \" id= \" buttonGroups \" >Groups</a></li> \n "
" <li><a href= \" javascript:void(0) \" onclick= \" SetMode( \' timers \' , 2); \" id= \" buttonThreads \" >Threads</a></li> \n "
" <li><a href= \" javascript:void(0) \" onclick= \" SetMode( \' detailed \' , 0); \" id= \" buttonDetailed \" >Detailed</a></li> \n "
" </ul> \n "
" </li> \n "
" <li><a>Reference</a> \n "
" <ul id= \' ReferenceSubMenu \' > \n "
" <li><a href= \" javascript:void(0) \" onclick= \" SetReferenceTime( \' 5ms \' ); \" >5ms</a></li> \n "
" <li><a href= \" javascript:void(0) \" onclick= \" SetReferenceTime( \' 10ms \' ); \" >10ms</a></li> \n "
" <li><a href= \" javascript:void(0) \" onclick= \" SetReferenceTime( \' 15ms \' ); \" >15ms</a></li> \n "
" <li><a href= \" javascript:void(0) \" onclick= \" SetReferenceTime( \' 20ms \' ); \" >20ms</a></li> \n "
" <li><a href= \" javascript:void(0) \" onclick= \" SetReferenceTime( \' 33ms \' ); \" >33ms</a></li> \n "
" <li><a href= \" javascript:void(0) \" onclick= \" SetReferenceTime( \' 50ms \' ); \" >50ms</a></li> \n "
" <li><a href= \" javascript:void(0) \" onclick= \" SetReferenceTime( \' 100ms \' ); \" >100ms</a></li> \n "
" <li><a href= \" javascript:void(0) \" onclick= \" SetReferenceTime( \' 250ms \' ); \" >250ms</a></li> \n "
" <li><a href= \" javascript:void(0) \" onclick= \" SetReferenceTime( \' 500ms \' ); \" >500ms</a></li> \n "
" <li><a href= \" javascript:void(0) \" onclick= \" SetReferenceTime( \' 1000ms \' ); \" >1000ms</a></li> \n "
" </ul> \n "
" </li> \n "
" <li id= \" ilThreads \" ><a>Threads</a> \n "
" <ul id= \" ThreadSubMenu \" > \n "
" <li><a href= \" javascript:void(0) \" onclick= \" ToggleThread(); \" >All</a></li> \n "
" <li><a>---</a></li> \n "
" </ul> \n "
" </li> \n "
" <li id= \" ilGroups \" ><a>Groups</a> \n "
" <ul id= \" GroupSubMenu \" > \n "
" <li><a href= \" javascript:void(0) \" onclick= \" ToggleGroup(); \" >All</a></li> \n "
" <li><a>---</a></li> \n "
" </ul> \n "
" </li> \n "
" <li id= \" ilOptions \" ><a>Options </a> \n "
" <ul id= \' OptionsMenu \' > \n "
" <li><a href= \" javascript:void(0) \" onclick= \" ToggleContextSwitch(); \" >Context Switch</a></li> \n "
" <li><a href= \" javascript:void(0) \" onclick= \" ToggleDisableMerge(); \" >MergeDisable</a></li> \n "
" <li><a href= \" javascript:void(0) \" onclick= \" ToggleDisableLod(); \" >LodDisable</a></li> \n "
" <li id= \' GroupColors \' ><a href= \" javascript:void(0) \" onclick= \" ToggleGroupColors(); \" >Group Colors</a></li> \n "
" <li id= \' TimersMeta \' ><a href= \" javascript:void(0) \" onclick= \" ToggleTimersMeta(); \" >Meta</a></li> \n "
" <li id= \' ShowHelp \' ><a href= \" javascript:void(0) \" onclick= \" ShowHelp(1,1); \" >Help</a></li> \n "
" <!-- <li><a href= \" javascript:void(0) \" onclick= \" ToggleDebug(); \" >DEBUG</a></li> --> \n "
" </ul> \n "
" </li> \n "
" </ul> \n "
" </div> \n "
" <script> \n "
" function InvertColor(hexTripletColor) { \n "
" var color = hexTripletColor; \n "
" color = color.substring(1); // remove # \n "
" color = parseInt(color, 16); // convert to integer \n "
" var R = ((color >> 16) % 256)/255.0; \n "
" var G = ((color >> 8) % 256)/255.0; \n "
" var B = ((color >> 0) % 256)/255.0; \n "
" var lum = (0.2126*R + 0.7152*G + 0.0722*B); \n "
" if(lum < 0.7) \n "
" { \n "
" return \' #ffffff \' ; \n "
" } \n "
" else \n "
" { \n "
" return \' #333333 \' ; \n "
" } \n "
" } \n "
" function InvertColorIndex(hexTripletColor) { \n "
" var color = hexTripletColor; \n "
" color = color.substring(1); // remove # \n "
" color = parseInt(color, 16); // convert to integer \n "
" var R = ((color >> 16) % 256)/255.0; \n "
" var G = ((color >> 8) % 256)/255.0; \n "
" var B = ((color >> 0) % 256)/255.0; \n "
" var lum = (0.2126*R + 0.7152*G + 0.0722*B); \n "
" if(lum < 0.7) \n "
" { \n "
" return 0; \n "
" } \n "
" else \n "
" { \n "
" return 1; \n "
" } \n "
" } \n "
" function MakeGroup(id, name, category, numtimers, isgpu, total, average, max, color) \n "
" { \n "
" var group = { \" id \" :id, \" name \" :name, \" category \" :category, \" numtimers \" :numtimers, \" isgpu \" :isgpu, \" total \" : total, \" average \" : average, \" max \" : max, \" color \" :color}; \n "
" return group; \n "
" } \n "
" \n "
" function MakeTimer(id, name, group, color, colordark, average, max, exclaverage, exclmax, callaverage, callcount, total, meta, metaavg, metamax) \n "
" { \n "
" var timer = { \" id \" :id, \" name \" :name, \" len \" :name.length, \" color \" :color, \" colordark \" :colordark, \" timercolor \" :color, \" textcolor \" :InvertColor(color), \" group \" :group, \" average \" :average, \" max \" :max, \" exclaverage \" :exclaverage, \" exclmax \" :exclmax, \" callaverage \" :callaverage, \" callcount \" :callcount, \" total \" :total, \" meta \" :meta, \" textcolorindex \" :InvertColorIndex(color), \" metaavg \" :metaavg, \" metamax \" :metamax}; \n "
" return timer; \n "
" } \n "
" function MakeFrame(id, framestart, frameend, framestartgpu, frameendgpu, ts, tt, ti) \n "
" { \n "
" var frame = { \" id \" :id, \" framestart \" :framestart, \" frameend \" :frameend, \" framestartgpu \" :framestartgpu, \" frameendgpu \" :frameendgpu, \" ts \" :ts, \" tt \" :tt, \" ti \" :ti}; \n "
" return frame; \n "
" } \n "
" \n "
" " ;
const size_t g_MicroProfileHtml_begin_0_size = sizeof ( g_MicroProfileHtml_begin_0 ) ;
const char * g_MicroProfileHtml_begin [ ] = {
& g_MicroProfileHtml_begin_0 [ 0 ] ,
} ;
size_t g_MicroProfileHtml_begin_sizes [ ] = {
sizeof ( g_MicroProfileHtml_begin_0 ) ,
} ;
size_t g_MicroProfileHtml_begin_count = 1 ;
const char g_MicroProfileHtml_end_0 [ ] =
" \n "
" \n "
" \n "
" var CanvasDetailedView = document.getElementById( \' DetailedView \' ); \n "
" var CanvasHistory = document.getElementById( \' History \' ); \n "
" var CanvasDetailedOffscreen = document.createElement( \' canvas \' ); \n "
" var g_Msg = \' 0 \' ; \n "
" \n "
" var Initialized = 0; \n "
" var fDetailedOffset = Frames[0].framestart; \n "
" var fDetailedRange = Frames[0].frameend - fDetailedOffset; \n "
" var nWidth = CanvasDetailedView.width; \n "
" var nHeight = CanvasDetailedView.height; \n "
" var ReferenceTime = 33; \n "
" var nHistoryHeight = 70; \n "
" var nOffsetY = 0; \n "
" var nOffsetBarsX = 0; \n "
" var nOffsetBarsY = 0; \n "
" var nBarsWidth = 80; \n "
" var NameWidth = 200; \n "
" var MouseButtonState = [0,0,0,0,0,0,0,0]; \n "
" var KeyShiftDown = 0; \n "
" var MouseDragButton = 0; \n "
" var KeyCtrlDown = 0; \n "
" var FlipToolTip = 0; \n "
" var DetailedViewMouseX = 0; \n "
" var DetailedViewMouseY = 0; \n "
" var HistoryViewMouseX = -1; \n "
" var HistoryViewMouseY = -1; \n "
" var MouseHistory = 0; \n "
" var MouseDetailed = 0; \n "
" var FontHeight = 10; \n "
" var FontWidth = 1; \n "
" var FontAscent = 3; //Set manually \n "
" var Font = \' Bold \' + FontHeight + \' px Courier New \' ; \n "
" var FontFlash = \' Bold \' + 35 + \' px Courier New \' ; \n "
" var BoxHeight = FontHeight + 2; \n "
" var ThreadsActive = new Object(); \n "
" var ThreadsAllActive = 1; \n "
" var GroupsActive = new Object(); \n "
" var GroupsAllActive = 1; \n "
" var nMinWidth = 0.01;//subpixel width \n "
" var nMinWidthPan = 1.0;//subpixel width when panning \n "
" var nContextSwitchEnabled = 1; \n "
" var DisableLod = 0; \n "
" var DisableMerge = 0; \n "
" var GroupColors = 0; \n "
" var nModDown = 0; \n "
" var g_MSG = \' no \' ; \n "
" var nDrawCount = 0; \n "
" var nBackColors = [ \' #474747 \' , \' #313131 \' ]; \n "
" var nBackColorOffset = \' #606060 \' ; \n "
" var CSwitchColors =[ \" #9DD8AF \" , \" #D7B6DA \" , \" #EAAC76 \" , \" #DBDA61 \" , \" #8AD5E1 \" , \" #8CE48B \" , \" #C4D688 \" , \" #57E5C4 \" ];//generated by http://tools.medialab.sciences-po.fr/iwanthue/index.php \n "
" var CSwitchHeight = 5; \n "
" var FRAME_HISTORY_COLOR_CPU = \' #ff7f27 \' ; \n "
" var FRAME_HISTORY_COLOR_GPU = \' #ffffff \' ; \n "
" var ZOOM_TIME = 0.5; \n "
" var AnimationActive = false; \n "
" var nHoverCSCpu = -1; \n "
" var nHoverCSCpuNext = -1; \n "
" var nHoverCSToolTip = null; \n "
" var nHoverToken = -1; \n "
" var nHoverFrame = -1; \n "
" var nHoverTokenIndex = -1; \n "
" var nHoverTokenLogIndex = -1; \n "
" var nHoverCounter = 0; \n "
" var nHoverCounterDelta = 8; \n "
" var nHoverTokenNext = -1; \n "
" var nHoverTokenLogIndexNext = -1; \n "
" var nHoverTokenIndexNext = -1; \n "
" var nHideHelp = 0; \n "
" \n "
" \n "
" var fFrameScale = 33.33; \n "
" var fRangeBegin = 0; \n "
" var fRangeEnd = -1; \n "
" var fRangeBeginNext = 0; \n "
" var fRangeEndNext = 0; \n "
" var fRangeBeginGpuNext = 0; \n "
" var fRangeEndGpuNext = 0; \n "
" var fRangeBeginHistory = -1; \n "
" var fRangeEndHistory = -1; \n "
" var fRangeBeginHistoryGpu = -1; \n "
" var fRangeEndHistoryGpu = -1; \n "
" var fRangeBeginSelect = 0; \n "
" var fRangeEndSelect = -1; \n "
" \n "
" var ModeDetailed = 0; \n "
" var ModeTimers = 1; \n "
" var Mode = ModeDetailed; \n "
" \n "
" var DebugDrawQuadCount = 0; \n "
" var DebugDrawTextCount = 0; \n "
" var ProfileMode = 0; \n "
" var ProfileFps = 0; \n "
" var ProfileFpsAggr = 0; \n "
" var ProfileFpsCount = 0; \n "
" var ProfileLastTimeStamp = new Date(); \n "
" \n "
" var CSwitchCache = {}; \n "
" var CSwitchOnlyThreads = []; \n "
" var ProfileData = {}; \n "
" var ProfileStackTime = {}; \n "
" var ProfileStackName = {}; \n "
" var Debug = 1; \n "
" \n "
" var g_MaxStack = Array(); \n "
" var g_TypeArray; \n "
" var g_TimeArray; \n "
" var g_IndexArray; \n "
" var LodData = new Array(); \n "
" var NumLodSplits = 10; \n "
" var SplitMin = 100; \n "
" var SPLIT_LIMIT = 1e20; \n "
" var DPR = 1; \n "
" var DetailedRedrawState = {}; \n "
" var OffscreenData; \n "
" var DetailedFrameCounter = 0; \n "
" var Invalidate = 0; \n "
" var GroupOrder = Array(); \n "
" var ThreadOrder = Array(); \n "
" var TimersGroups = 0; \n "
" var TimersMeta = 1; \n "
" var MetaLengths = Array(); \n "
" var MetaLengthsAvg = Array(); \n "
" var MetaLengthsMax = Array(); \n "
" \n "
" \n "
" function ProfileModeClear() \n "
" { \n "
" if(ProfileMode) \n "
" { \n "
" ProfileData = new Object(); \n "
" ProfileStackTime = new Array(); \n "
" ProfileStackName = new Array(); \n "
" } \n "
" } \n "
" function ProfileEnter(Name) \n "
" { \n "
" if(ProfileMode) \n "
" { \n "
" ProfileStackTime.push(new Date()); \n "
" ProfileStackName.push(Name); \n "
" } \n "
" } \n "
" function ProfileLeave() \n "
" { \n "
" if(ProfileMode) \n "
" { \n "
" var Time = new Date(); \n "
" var Delta = Time - ProfileStackTime.pop(); \n "
" var Name = ProfileStackName.pop(); \n "
" var Obj = ProfileData[Name]; \n "
" if(!Obj) \n "
" { \n "
" Obj = new Object(); \n "
" Obj.Count = 0; \n "
" Obj.Name = Name; \n "
" Obj.Time = 0; \n "
" ProfileData[Name] = Obj; \n "
" } \n "
" Obj.Time += Delta; \n "
" Obj.Count += 1; \n "
" } \n "
" } \n "
" \n "
" function ProfilePlot(s) \n "
" { \n "
" if(ProfileMode) \n "
" { \n "
" var A = ProfileData.Plot; \n "
" if(!A) \n "
" { \n "
" ProfileData.Plot = Array(); \n "
" A = ProfileData.Plot; \n "
" } \n "
" if(A.length<10) \n "
" { \n "
" A.push(s); \n "
" } \n "
" } \n "
" } \n "
" function ProfileModeDump() \n "
" { \n "
" for(var idx in ProfileData) \n "
" { \n "
" var Timer = ProfileData[idx]; \n "
" console.log(Timer.Name + \" \" + Timer.Time + \" ms \" + Timer.Count); \n "
" } \n "
" \n "
" } \n "
" function ProfileModeDraw(Canvas) \n "
" { \n "
" if(ProfileMode) \n "
" { \n "
" var StringArray = []; \n "
" for(var idx in ProfileData) \n "
" { \n "
" if(idx == \" Plot \" ) \n "
" continue; \n "
" var Timer = ProfileData[idx]; \n "
" StringArray.push(Timer.Name); \n "
" StringArray.push(Timer.Time + \" ms \" ); \n "
" StringArray.push( \" # \" ); \n "
" StringArray.push( \" \" + Timer.Count); \n "
" } \n "
" StringArray.push( \" debug \" ); \n "
" StringArray.push(Debug); \n "
" var Time = new Date(); \n "
" var Delta = Time - ProfileLastTimeStamp; \n "
" ProfileLastTimeStamp = Time; \n "
" StringArray.push( \" Frame Delta \" ); \n "
" StringArray.push(Delta + \" ms \" ); \n "
" if(ProfileMode == 2) \n "
" { \n "
" ProfileFpsAggr += Delta; \n "
" ProfileFpsCount ++ ; \n "
" var AggrFrames = 10; \n "
" if(ProfileFpsCount == AggrFrames) \n "
" { \n "
" ProfileFps = 1000 / (ProfileFpsAggr / AggrFrames); \n "
" ProfileFpsAggr = 0; \n "
" ProfileFpsCount = 0; \n "
" } \n "
" StringArray.push( \" FPS \" ); \n "
" StringArray.push( \" \" + ProfileFps.toFixed(2)); \n "
" } \n "
" \n "
" \n "
" for(var i = 0; i < ProfileData.Plot; ++i) \n "
" { \n "
" StringArray.push( \" \" ); \n "
" StringArray.push(ProfileData.Plot[i]); \n "
" } \n "
" ProfileData.Plot = Array(); \n "
" DrawToolTip(StringArray, Canvas, 0, 200); \n "
" } \n "
" } \n "
" \n "
" function ToggleDebugMode() \n "
" { \n "
" ProfileMode = (ProfileMode+1)%4; \n "
" console.log( \' Toggle Debug Mode \' + ProfileMode); \n "
" } \n "
" \n "
" function DetailedTotal() \n "
" { \n "
" var Total = 0; \n "
" for(var i = 0; i < Frames.length; i++) \n "
" { \n "
" var frfr = Frames[i]; \n "
" Total += frfr.frameend - frfr.framestart; \n "
" } \n "
" return Total; \n "
" } \n "
" \n "
" function InitFrameInfo() \n "
" { \n "
" \n "
" var div = document.getElementById( \' divFrameInfo \' ); \n "
" var txt = \' \' ; \n "
" txt = txt + \' Timers View \' + \' <br> \' ; \n "
" txt = txt + \' Frames: \' + AggregateInfo.Frames + \' <br> \' ; \n "
" txt = txt + \' Time: \' + AggregateInfo.Time.toFixed(2) + \' ms<br> \' ; \n "
" txt = txt + \' <hr> \' ; \n "
" txt = txt + \' Detailed View \' + \' <br> \' ; \n "
" txt = txt + \' Frames: \' + Frames.length + \' <br> \' ; \n "
" txt = txt + \' Time: \' + DetailedTotal().toFixed(2) + \' ms<br> \' ; \n "
" div.innerHTML = txt; \n "
" } \n "
" function InitGroups() \n "
" { \n "
" for(groupid in GroupInfo) \n "
" { \n "
" var TimerArray = Array(); \n "
" for(timerid in TimerInfo) \n "
" { \n "
" if(TimerInfo[timerid].group == groupid) \n "
" { \n "
" TimerArray.push(timerid); \n "
" } \n "
" } \n "
" GroupInfo[groupid].TimerArray = TimerArray; \n "
" } \n "
" } \n "
" \n "
" function InitThreadMenu() \n "
" { \n "
" var ulThreadMenu = document.getElementById( \' ThreadSubMenu \' ); \n "
" var MaxLen = 7; \n "
" ThreadOrder = CreateOrderArray(ThreadNames, function(a){return a;}); \n "
" for(var idx in ThreadOrder) \n "
" { \n "
" var name = ThreadNames[ThreadOrder[idx]]; \n "
" var li = document.createElement( \' li \' ); \n "
" if(name.length > MaxLen) \n "
" { \n "
" MaxLen = name.length; \n "
" } \n "
" li.innerText = name; \n "
" var asText = li.innerHTML; \n "
" var html = \' <a href= \" javascript:void(0) \" onclick= \" ToggleThread( \\ ' \' + name + \' \\ '); \" > \' + asText + \' </a> \' ; \n "
" li.innerHTML = html; \n "
" ulThreadMenu.appendChild(li); \n "
" } \n "
" var LenStr = (5+(1+MaxLen) * (1+FontWidth)) + \' px \' ; \n "
" var Lis = ulThreadMenu.getElementsByTagName( \' li \' ); \n "
" for(var i = 0; i < Lis.length; ++i) \n "
" { \n "
" Lis[i].style[ \' width \' ] = LenStr; \n "
" } \n "
" } \n "
" \n "
" function UpdateThreadMenu() \n "
" { \n "
" var ulThreadMenu = document.getElementById( \' ThreadSubMenu \' ); \n "
" var as = ulThreadMenu.getElementsByTagName( \' a \' ); \n "
" for(var i = 0; i < as.length; ++i) \n "
" { \n "
" var elem = as[i]; \n "
" var inner = elem.innerText; \n "
" var bActive = false; \n "
" if(i < 2) \n "
" { \n "
" if(inner == \' All \' ) \n "
" { \n "
" bActive = ThreadsAllActive; \n "
" } \n "
" } \n "
" else \n "
" { \n "
" bActive = ThreadsActive[inner]; \n "
" } \n "
" if(bActive) \n "
" { \n "
" elem.style[ \' text-decoration \' ] = \' underline \' ; \n "
" } \n "
" else \n "
" { \n "
" elem.style[ \' text-decoration \' ] = \' none \' ; \n "
" } \n "
" } \n "
" } \n "
" \n "
" function ToggleThread(ThreadName) \n "
" { \n "
" if(ThreadName) \n "
" { \n "
" if(ThreadsActive[ThreadName]) \n "
" { \n "
" ThreadsActive[ThreadName] = false; \n "
" } \n "
" else \n "
" { \n "
" ThreadsActive[ThreadName] = true; \n "
" } \n "
" } \n "
" else \n "
" { \n "
" if(ThreadsAllActive) \n "
" { \n "
" ThreadsAllActive = 0; \n "
" } \n "
" else \n "
" { \n "
" ThreadsAllActive = 1; \n "
" } \n "
" } \n "
" Invalidate = 0; \n "
" UpdateThreadMenu(); \n "
" WriteCookie(); \n "
" Draw(1); \n "
" \n "
" } \n "
" \n "
" function CreateOrderArray(Source, NameFunc) \n "
" { \n "
" var Temp = Array(Source.length); \n "
" for(var i = 0; i < Source.length; ++i) \n "
" { \n "
" Temp[i] = {}; \n "
" Temp[i].index = i; \n "
" Temp[i].namezz = NameFunc(Source[i]).toLowerCase(); \n "
" } \n "
" Temp.sort(function(l, r) \n "
" { \n "
" if(r.namezz<l.namezz) \n "
" {return 1;} \n "
" if(l.namezz<r.namezz) \n "
" {return -1;} \n "
" return 0; \n "
" } ); \n "
" var OrderArray = Array(Source.length); \n "
" for(var i = 0; i < Source.length; ++i) \n "
" { \n "
" OrderArray[i] = Temp[i].index; \n "
" } \n "
" return OrderArray; \n "
" } \n "
" \n "
" \n "
" function InitGroupMenu() \n "
" { \n "
" var ulGroupMenu = document.getElementById( \' GroupSubMenu \' ); \n "
" var MaxLen = 7; \n "
" var MenuArray = Array(); \n "
" for(var i = 0; i < GroupInfo.length; ++i) \n "
" { \n "
" var x = {}; \n "
" x.IsCategory = 0; \n "
" x.category = GroupInfo[i].category; \n "
" x.name = GroupInfo[i].name; \n "
" x.index = i; \n "
" MenuArray.push(x); \n "
" } \n "
" for(var i = 0; i < CategoryInfo.length; ++i) \n "
" { \n "
" var x = {}; \n "
" x.IsCategory = 1; \n "
" x.category = i; \n "
" x.name = CategoryInfo[i]; \n "
" x.index = i; \n "
" MenuArray.push(x); \n "
" } \n "
" var OrderFunction = function(a){ return a.category + \" __ \" + a.name; }; \n "
" var OrderFunctionMenu = function(a){ return a.IsCategory ? (a.category + \' \' ) : (a.category + \" __ \" + a.name); }; \n "
" GroupOrder = CreateOrderArray(GroupInfo, OrderFunction); \n "
" var MenuOrder = CreateOrderArray(MenuArray, OrderFunctionMenu); \n "
" \n "
" for(var idx in MenuOrder) \n "
" { \n "
" var MenuItem = MenuArray[MenuOrder[idx]]; \n "
" var name = MenuItem.name; \n "
" var li = document.createElement( \' li \' ); \n "
" if(name.length > MaxLen) \n "
" { \n "
" MaxLen = name.length; \n "
" } \n "
" var jsfunc = \' \' ; \n "
" if(MenuItem.IsCategory) \n "
" { \n "
" li.innerText = \' [ \' + name + \' ] \' ; \n "
" jsfunc = \" ToggleCategory \" ; \n "
" } \n "
" else \n "
" { \n "
" li.innerText = name; \n "
" jsfunc = \" ToggleGroup \" ; \n "
" } \n "
" var asText = li.innerHTML; \n "
" var html = \' <a href= \" javascript:void(0) \" onclick= \" \' + jsfunc + \' ( \\ ' \' + name + \' \\ '); \" > \' + asText + \' </a> \' ; \n "
" li.innerHTML = html; \n "
" ulGroupMenu.appendChild(li); \n "
" } \n "
" var LenStr = (5+(1+MaxLen) * FontWidth) + \' px \' ; \n "
" var Lis = ulGroupMenu.getElementsByTagName( \' li \' ); \n "
" for(var i = 0; i < Lis.length; ++i) \n "
" { \n "
" Lis[i].style[ \' width \' ] = LenStr; \n "
" } \n "
" UpdateGroupMenu(); \n "
" } \n "
" \n "
" function UpdateGroupMenu() \n "
" { \n "
" var ulThreadMenu = document.getElementById( \' GroupSubMenu \' ); \n "
" var as = ulThreadMenu.getElementsByTagName( \' a \' ); \n "
" for(var i = 0; i < as.length; ++i) \n "
" { \n "
" var elem = as[i]; \n "
" var inner = elem.innerText; \n "
" var bActive = false; \n "
" if(i < 2) \n "
" { \n "
" if(inner == \' All \' ) \n "
" { \n "
" bActive = GroupsAllActive; \n "
" } \n "
" } \n "
" else \n "
" { \n "
" var CategoryString = inner.length>2 ? inner.substring(1, inner.length-2) : \" \" ; \n "
" var CategoryIdx = CategoryIndex(CategoryString); \n "
" if(inner[0] == \' [ \' && inner[inner.length-1] == \' ] \' && CategoryIdx >= 0) \n "
" { \n "
" bActive = IsCategoryActive(CategoryIdx); \n "
" } \n "
" else \n "
" { \n "
" bActive = GroupsActive[inner]; \n "
" } \n "
" } \n "
" if(bActive) \n "
" { \n "
" elem.style[ \' text-decoration \' ] = \' underline \' ; \n "
" } \n "
" else \n "
" { \n "
" elem.style[ \' text-decoration \' ] = \' none \' ; \n "
" } \n "
" } \n "
" } \n "
" function CategoryIndex(CategoryName) \n "
" { \n "
" for(var i = 0; i < CategoryInfo.length; ++i) \n "
" { \n "
" if(CategoryInfo[i] == CategoryName) \n "
" { \n "
" return i; \n "
" } \n "
" } \n "
" return -1; \n "
" } \n "
" function IsCategoryActive(CategoryIdx) \n "
" { \n "
" for(var i = 0; i < GroupInfo.length; ++i) \n "
" { \n "
" if(GroupInfo[i].category == CategoryIdx) \n "
" { \n "
" var Name = GroupInfo[i].name; \n "
" if(!GroupsActive[Name]) \n "
" { \n "
" return false; \n "
" } \n "
" } \n "
" } \n "
" return true; \n "
" \n "
" } \n "
" function ToggleCategory(CategoryName) \n "
" { \n "
" var CategoryIdx = CategoryIndex(CategoryName); \n "
" if(CategoryIdx < 0) \n "
" return; \n "
" var CategoryActive = IsCategoryActive(CategoryIdx); \n "
" for(var i = 0; i < GroupInfo.length; ++i) \n "
" { \n "
" if(GroupInfo[i].category == CategoryIdx) \n "
" { \n "
" var Name = GroupInfo[i].name; \n "
" if(CategoryActive) \n "
" { \n "
" GroupsActive[Name] = false; \n "
" } \n "
" else \n "
" { \n "
" GroupsActive[Name] = true; \n "
" } \n "
" } \n "
" } \n "
" UpdateGroupMenu(); \n "
" WriteCookie(); \n "
" RequestRedraw(); \n "
" } \n "
" \n "
" function ToggleGroup(GroupName) \n "
" { \n "
" if(GroupName) \n "
" { \n "
" if(GroupsActive[GroupName]) \n "
" { \n "
" GroupsActive[GroupName] = false; \n "
" } \n "
" else \n "
" { \n "
" GroupsActive[GroupName] = true; \n "
" } \n "
" } \n "
" else \n "
" { \n "
" if(GroupsAllActive) \n "
" { \n "
" GroupsAllActive = 0; \n "
" } \n "
" else \n "
" { \n "
" GroupsAllActive = 1; \n "
" } \n "
" } \n "
" UpdateGroupMenu(); \n "
" WriteCookie(); \n "
" RequestRedraw(); \n "
" } \n "
" function UpdateGroupColors() \n "
" { \n "
" for(var i = 0; i < TimerInfo.length; ++i) \n "
" { \n "
" if(GroupColors) \n "
" { \n "
" TimerInfo[i].color = GroupInfo[TimerInfo[i].group].color; \n "
" } \n "
" else \n "
" { \n "
" TimerInfo[i].color = TimerInfo[i].timercolor; \n "
" } \n "
" TimerInfo[i].textcolorindex = InvertColorIndex(TimerInfo[i].color); \n "
" } \n "
" } \n "
" \n "
" function ToggleGroupColors() \n "
" { \n "
" GroupColors = !GroupColors; \n "
" UpdateGroupColors(); \n "
" UpdateOptionsMenu(); \n "
" WriteCookie(); \n "
" RequestRedraw(); \n "
" } \n "
" \n "
" function UpdateOptionsMenu() \n "
" { \n "
" var ulTimersMeta = document.getElementById( \' TimersMeta \' ); \n "
" ulTimersMeta.style[ \' text-decoration \' ] = TimersMeta ? \' underline \' : \' none \' ; \n "
" var ulGroupColors = document.getElementById( \' GroupColors \' ); \n "
" ulGroupColors.style[ \' text-decoration \' ] = GroupColors ? \' underline \' : \' none \' ; \n "
" } \n "
" \n "
" function ToggleTimersMeta() \n "
" { \n "
" TimersMeta = TimersMeta ? 0 : 1; \n "
" WriteCookie(); \n "
" UpdateOptionsMenu(); \n "
" RequestRedraw(); \n "
" } \n "
" \n "
" function ShowHelp(Show, Forever) \n "
" { \n "
" var HelpWindow = document.getElementById( \' helpwindow \' ); \n "
" if(Show) \n "
" { \n "
" HelpWindow.style[ \' display \' ] = \' block \' ; \n "
" } \n "
" else \n "
" { \n "
" HelpWindow.style[ \' display \' ] = \' none \' ; \n "
" } \n "
" if(Forever) \n "
" { \n "
" nHideHelp = Show ? 0 : 1; \n "
" WriteCookie(); \n "
" } \n "
" } \n "
" function SetMode(NewMode, Groups) \n "
" { \n "
" var buttonTimers = document.getElementById( \' buttonTimers \' ); \n "
" var buttonDetailed = document.getElementById( \' buttonDetailed \' ); \n "
" var buttonGroups = document.getElementById( \' buttonGroups \' ); \n "
" var buttonThreads = document.getElementById( \' buttonThreads \' ); \n "
" var ilThreads = document.getElementById( \' ilThreads \' ); \n "
" var ilGroups = document.getElementById( \' ilGroups \' ); \n "
" var ModeElement = null; \n "
" if(NewMode == \' timers \' || NewMode == ModeTimers) \n "
" { \n "
" TimersGroups = Groups; \n "
" buttonTimers.style[ \' text-decoration \' ] = TimersGroups ? \' none \' : \' underline \' ; \n "
" buttonGroups.style[ \' text-decoration \' ] = TimersGroups == 1 ? \' underline \' : \' none \' ; \n "
" buttonThreads.style[ \' text-decoration \' ] = TimersGroups == 2 ? \' underline \' : \' none \' ; \n "
" buttonDetailed.style[ \' text-decoration \' ] = \' none \' ; \n "
" if(TimersGroups == 0) \n "
" { \n "
" ilThreads.style[ \' display \' ] = \' none \' ; \n "
" } \n "
" else \n "
" { \n "
" ilThreads.style[ \' display \' ] = \' block \' ; \n "
" } \n "
" ilGroups.style[ \' display \' ] = \' block \' ; \n "
" Mode = ModeTimers; \n "
" ModeElement = TimersGroups == 2 ? buttonThreads : TimersGroups == 1 ? buttonGroups : buttonTimers; \n "
" } \n "
" else if(NewMode == \' detailed \' || NewMode == ModeDetailed) \n "
" { \n "
" buttonTimers.style[ \' text-decoration \' ] = \' none \' ; \n "
" buttonGroups.style[ \' text-decoration \' ] = \' none \' ; \n "
" buttonThreads.style[ \' text-decoration \' ] = \' none \' ; \n "
" buttonDetailed.style[ \' text-decoration \' ] = \' underline \' ; \n "
" ilThreads.style[ \' display \' ] = \' block \' ; \n "
" ilGroups.style[ \' display \' ] = \' none \' ; \n "
" Mode = ModeDetailed; \n "
" ModeElement = buttonDetailed; \n "
" } \n "
" var ModeSubMenuText = document.getElementById( \' ModeSubMenuText \' ); \n "
" ModeSubMenuText.innerText = \' Mode[ \' + ModeElement.innerText + \' ] \' ; \n "
" \n "
" WriteCookie(); \n "
" RequestRedraw(); \n "
" \n "
" } \n "
" \n "
" function SetReferenceTime(TimeString) \n "
" { \n "
" ReferenceTime = parseInt(TimeString); \n "
" var ReferenceMenu = document.getElementById( \' ReferenceSubMenu \' ); \n "
" var Links = ReferenceMenu.getElementsByTagName( \' a \' ); \n "
" for(var i = 0; i < Links.length; ++i) \n "
" { \n "
" if(Links[i].innerHTML.match( \' ^ \' + TimeString)) \n "
" { \n "
" Links[i].style[ \' text-decoration \' ] = \' underline \' ; \n "
" } \n "
" else \n "
" { \n "
" Links[i].style[ \' text-decoration \' ] = \' none \' ; \n "
" } \n "
" } \n "
" WriteCookie(); \n "
" RequestRedraw(); \n "
" \n "
" } \n "
" \n "
" function ToggleContextSwitch() \n "
" { \n "
" SetContextSwitch(nContextSwitchEnabled ? 0 : 1); \n "
" } \n "
" function SetContextSwitch(Enabled) \n "
" { \n "
" nContextSwitchEnabled = Enabled ? 1 : 0; \n "
" var ReferenceMenu = document.getElementById( \' OptionsMenu \' ); \n "
" var Links = ReferenceMenu.getElementsByTagName( \' a \' ); \n "
" Links[0].style[ \' text-decoration \' ] = nContextSwitchEnabled ? \' underline \' : \' none \' ; \n "
" WriteCookie(); \n "
" RequestRedraw(); \n "
" } \n "
" \n "
" function ToggleDebug() \n "
" { \n "
" Debug = (Debug + 1) % 2; \n "
" } \n "
" \n "
" function ToggleDisableMerge() \n "
" { \n "
" DisableMerge = DisableMerge ? 0 : 1; \n "
" var ReferenceMenu = document.getElementById( \' OptionsMenu \' ); \n "
" var Links = ReferenceMenu.getElementsByTagName( \' a \' ); \n "
" if(DisableMerge) \n "
" { \n "
" Links[1].style[ \' text-decoration \' ] = \' underline \' ; \n "
" } \n "
" else \n "
" { \n "
" Links[1].style[ \' text-decoration \' ] = \' none \' ; \n "
" } \n "
" \n "
" } \n "
" \n "
" function ToggleDisableLod() \n "
" { \n "
" DisableLod = DisableLod ? 0 : 1; \n "
" var ReferenceMenu = document.getElementById( \' OptionsMenu \' ); \n "
" var Links = ReferenceMenu.getElementsByTagName( \' a \' ); \n "
" if(DisableLod) \n "
" { \n "
" Links[2].style[ \' text-decoration \' ] = \' underline \' ; \n "
" } \n "
" else \n "
" { \n "
" Links[2].style[ \' text-decoration \' ] = \' none \' ; \n "
" } \n "
" \n "
" } \n "
" \n "
" function GatherHoverMetaCounters(TimerIndex, StartIndex, nLog, nFrameLast) \n "
" { \n "
" var HoverInfo = new Object(); \n "
" var StackPos = 1; \n "
" //search backwards, count meta counters \n "
" for(var i = nFrameLast; i >= 0; i--) \n "
" { \n "
" var fr = Frames[i]; \n "
" var ts = fr.ts[nLog]; \n "
" var ti = fr.ti[nLog]; \n "
" var tt = fr.tt[nLog]; \n "
" var start = i == nFrameLast ? StartIndex-1 : ts.length-1; \n "
" \n "
" for(var j = start; j >= 0; j--) \n "
" { \n "
" var type = tt[j]; \n "
" var index = ti[j]; \n "
" var time = ts[j]; \n "
" if(type == 1) \n "
" { \n "
" StackPos--; \n "
" if(StackPos == 0 && index == TimerIndex) \n "
" { \n "
" return HoverInfo; \n "
" } \n "
" } \n "
" else if(type == 0) \n "
" { \n "
" StackPos++; \n "
" } \n "
" else if(type > 3) \n "
" { \n "
" var nMetaCount = type - 3; \n "
" var nMetaIndex = MetaNames[index]; \n "
" if(nMetaIndex in HoverInfo) \n "
" { \n "
" HoverInfo[nMetaIndex] += nMetaCount; \n "
" } \n "
" else \n "
" { \n "
" HoverInfo[nMetaIndex] = nMetaCount; \n "
" } \n "
" } \n "
" } \n "
" } \n "
" } \n "
" function CalculateAllTimers(fBegin, fEnd) \n "
" { \n "
" var Sum = []; \n "
" var Count = []; \n "
" var Sorted = []; \n "
" for(var i = 0; i < TimerInfo.length; ++i) \n "
" { \n "
" Sum.push(0.0); \n "
" Count.push(0); \n "
" Sorted.push(i); \n "
" } \n "
" var nFrameFirst = 0; \n "
" var nFrameLast = Frames.length; \n "
" \n "
" var nNumLogs = Frames[0].ts.length; \n "
" var StackPosArray = Array(nNumLogs); \n "
" var StackArray = Array(nNumLogs); \n "
" for(var i = 0; i < nNumLogs; ++i) \n "
" { \n "
" StackPosArray[i] = 0; \n "
" StackArray[i] = Array(20); \n "
" } \n "
" \n "
" for(var i = nFrameFirst; i < nFrameLast; i++) \n "
" { \n "
" var fr = Frames[i]; \n "
" for(nLog = 0; nLog < nNumLogs; nLog++) \n "
" { \n "
" var StackPos = StackPosArray[nLog]; \n "
" var Stack = StackArray[nLog]; \n "
" var ts = fr.ts[nLog]; \n "
" var ti = fr.ti[nLog]; \n "
" var tt = fr.tt[nLog]; \n "
" var count = ts.length; \n "
" for(j = 0; j < count; j++) \n "
" { \n "
" var type = tt[j]; \n "
" var index = ti[j]; \n "
" var time = ts[j]; \n "
" if(type == 1 && time < fEnd) //enter \n "
" { \n "
" Stack[StackPos] = time < fBegin ? fBegin : time; \n "
" if(StackArray[nLog][StackPos] != time) \n "
" { \n "
" console.log( \' fail fail fail \' ); \n "
" } \n "
" StackPos++; \n "
" } \n "
" else if(type == 0) // leave \n "
" { \n "
" if(StackPos>0) \n "
" { \n "
" var timeend = time; \n "
" StackPos--; \n "
" timestart = Stack[StackPos]; \n "
" var TimeDelta = timeend - timestart; \n "
" Sum[index] += TimeDelta; \n "
" Count[index]++; \n "
" } \n "
" } \n "
" } \n "
" StackPosArray[nLog] = StackPos; \n "
" } \n "
" } \n "
" Sorted.sort(function(a,b){ return Sum[b] - Sum[a]; } ); \n "
" var Result = { \" Sorted \" : Sorted, \" Sum \" : Sum, \" Count \" : Count}; \n "
" return Result; \n "
" } \n "
" function CalculateTimers(Result, TimerIndex, nFrameFirst, nFrameLast) \n "
" { \n "
" if(!nFrameFirst || nFrameFirst < 0) \n "
" nFrameFirst = 0; \n "
" if(!nFrameLast || nFrameLast > Frames.length) \n "
" nFrameLast = Frames.length; \n "
" var FrameCount = nFrameLast - nFrameFirst; \n "
" if(0 == FrameCount) \n "
" return; \n "
" var CallCount = 0; \n "
" var Sum = 0; \n "
" var Max = 0; \n "
" var FrameMax = 0; \n "
" \n "
" var nNumLogs = Frames[0].ts.length; \n "
" var StackPosArray = Array(nNumLogs); \n "
" var StackArray = Array(nNumLogs); \n "
" for(var i = 0; i < nNumLogs; ++i) \n "
" { \n "
" StackPosArray[i] = 0; \n "
" StackArray[i] = Array(20); \n "
" } \n "
" \n "
" for(var i = nFrameFirst; i < nFrameLast; i++) \n "
" { \n "
" var FrameSum = 0; \n "
" var fr = Frames[i]; \n "
" for(nLog = 0; nLog < nNumLogs; nLog++) \n "
" { \n "
" var StackPos = StackPosArray[nLog]; \n "
" var Stack = StackArray[nLog]; \n "
" var ts = fr.ts[nLog]; \n "
" var ti = fr.ti[nLog]; \n "
" var tt = fr.tt[nLog]; \n "
" var count = ts.length; \n "
" for(j = 0; j < count; j++) \n "
" { \n "
" var type = tt[j]; \n "
" var index = ti[j]; \n "
" var time = ts[j]; \n "
" if(type == 1) //enter \n "
" { \n "
" //push \n "
" Stack[StackPos] = time; \n "
" if(StackArray[nLog][StackPos] != time) \n "
" { \n "
" console.log( \' fail fail fail \' ); \n "
" } \n "
" StackPos++; \n "
" } \n "
" else if(type == 0) // leave \n "
" { \n "
" var timestart; \n "
" var timeend = time; \n "
" if(StackPos>0) \n "
" { \n "
" StackPos--; \n "
" timestart = Stack[StackPos]; \n "
" } \n "
" else \n "
" { \n "
" timestart = Frames[nFrameFirst].framestart; \n "
" } \n "
" if(index == TimerIndex) \n "
" { \n "
" var TimeDelta = timeend - timestart; \n "
" CallCount++; \n "
" FrameSum += TimeDelta; \n "
" Sum += TimeDelta; \n "
" if(TimeDelta > Max) \n "
" Max = TimeDelta; \n "
" } \n "
" } \n "
" else \n "
" { \n "
" //meta \n "
" } \n "
" } \n "
" if(FrameSum > FrameMax) \n "
" { \n "
" FrameMax = FrameSum; \n "
" } \n "
" StackPosArray[nLog] = StackPos; \n "
" } \n "
" } \n "
" \n "
" Result.CallCount = CallCount; \n "
" Result.Sum = Sum.toFixed(3); \n "
" Result.Max = Max.toFixed(3); \n "
" Result.Average = (Sum / CallCount).toFixed(3); \n "
" Result.FrameAverage = (Sum / FrameCount).toFixed(3); \n "
" Result.FrameCallAverage = (CallCount / FrameCount).toFixed(3); \n "
" Result.FrameMax = FrameMax.toFixed(3); \n "
" return Result; \n "
" } \n "
" \n "
" function PreprocessCalculateAllTimers() \n "
" { \n "
" ProfileEnter( \" CalculateAllTimers \" ); \n "
" var nFrameFirst = 0; \n "
" var nFrameLast = Frames.length; \n "
" var FrameCount = nFrameLast - nFrameFirst; \n "
" if(0 == FrameCount) \n "
" return; \n "
" for(var j = 0; j < TimerInfo.length; j++) \n "
" { \n "
" TimerInfo[j].CallCount = 0; \n "
" TimerInfo[j].Sum = 0; \n "
" TimerInfo[j].Max = 0; \n "
" TimerInfo[j].FrameMax = 0; \n "
" } \n "
" \n "
" \n "
" var nNumLogs = Frames[0].ts.length; \n "
" var StackPosArray = Array(nNumLogs); \n "
" var StackArray = Array(nNumLogs); \n "
" for(var i = 0; i < nNumLogs; ++i) \n "
" { \n "
" StackPosArray[i] = 0; \n "
" StackArray[i] = Array(20); \n "
" } \n "
" \n "
" for(var i = nFrameFirst; i < nFrameLast; i++) \n "
" { \n "
" for(var j = 0; j < TimerInfo.length; j++) \n "
" { \n "
" TimerInfo[j].FrameSum = 0; \n "
" } \n "
" \n "
" var fr = Frames[i]; \n "
" for(nLog = 0; nLog < nNumLogs; nLog++) \n "
" { \n "
" var StackPos = StackPosArray[nLog]; \n "
" var Stack = StackArray[nLog]; \n "
" var ts = fr.ts[nLog]; \n "
" var ti = fr.ti[nLog]; \n "
" var tt = fr.tt[nLog]; \n "
" var count = ts.length; \n "
" for(j = 0; j < count; j++) \n "
" { \n "
" var type = tt[j]; \n "
" var index = ti[j]; \n "
" var time = ts[j]; \n "
" if(type == 1) //enter \n "
" { \n "
" //push \n "
" Stack[StackPos] = time; \n "
" if(StackArray[nLog][StackPos] != time) \n "
" { \n "
" console.log( \' fail fail fail \' ); \n "
" } \n "
" StackPos++; \n "
" } \n "
" else if(type == 0) // leave \n "
" { \n "
" var timestart; \n "
" var timeend = time; \n "
" if(StackPos>0) \n "
" { \n "
" StackPos--; \n "
" timestart = Stack[StackPos]; \n "
" } \n "
" else \n "
" { \n "
" timestart = Frames[nFrameFirst].framestart; \n "
" } \n "
" // if(index == TimerIndex) \n "
" { \n "
" var TimeDelta = timeend - timestart; \n "
" TimerInfo[index].CallCount++; \n "
" TimerInfo[index].FrameSum += TimeDelta; \n "
" TimerInfo[index].Sum += TimeDelta; \n "
" if(TimeDelta > TimerInfo[index].Max) \n "
" TimerInfo[index].Max = TimeDelta; \n "
" } \n "
" } \n "
" else \n "
" { \n "
" //meta \n "
" } \n "
" } \n "
" for(var j = 0; j < TimerInfo.length; j++) \n "
" { \n "
" if(TimerInfo[j].FrameSum > TimerInfo[j].FrameMax) \n "
" { \n "
" TimerInfo[j].FrameMax = TimerInfo[j].FrameSum; \n "
" } \n "
" } \n "
" StackPosArray[nLog] = StackPos; \n "
" } \n "
" \n "
" \n "
" } \n "
" \n "
" for(var j = 0; j < TimerInfo.length; j++) \n "
" { \n "
" var CallCount = TimerInfo[j].CallCount; \n "
" var Sum = TimerInfo[j].Sum.toFixed(3); \n "
" var Max = TimerInfo[j].Max.toFixed(3); \n "
" var Average = (TimerInfo[j].Sum / TimerInfo[j].CallCount).toFixed(3); \n "
" var FrameAverage = (TimerInfo[j].Sum / FrameCount).toFixed(3); \n "
" var FrameCallAverage = (TimerInfo[j].CallCount / FrameCount).toFixed(3); \n "
" var FrameMax = TimerInfo[j].FrameMax.toFixed(3); \n "
" TimerInfo[j].CallCount = CallCount; \n "
" TimerInfo[j].Sum = Sum; \n "
" TimerInfo[j].Max = Max ; \n "
" TimerInfo[j].Average = Average; \n "
" TimerInfo[j].FrameAverage = FrameAverage; \n "
" TimerInfo[j].FrameCallAverage = FrameCallAverage; \n "
" TimerInfo[j].FrameMax = FrameMax; \n "
" } \n "
" ProfileLeave(); \n "
" } \n "
" \n "
" var FlashFrames = 10; \n "
" var FlashFrameCounter = 0; \n "
" var FlashMessage = \' \' ; \n "
" function TimeString(Diff) \n "
" { \n "
" var DiffString = \" 0 sec \" ; \n "
" var DiffTable = [1,60,60*60,60*60*24]; \n "
" var DiffNameTable = [ \" sec \" , \" min \" , \" hr \" , \" day \" ]; \n "
" for(var i = 0; i < DiffTable.length; ++i) \n "
" { \n "
" if(Diff >= DiffTable[i]) \n "
" { \n "
" DiffString = Math.floor(Diff / DiffTable[i]) + \" \" + DiffNameTable[i]; \n "
" } \n "
" } \n "
" return DiffString; \n "
" \n "
" } \n "
" function ShowFlashMessage(Message, FrameCount) \n "
" { \n "
" FlashMessage = Message; \n "
" FlashFrameCounter = FrameCount; \n "
" } \n "
" function OnPageReady() \n "
" { \n "
" var DumpDate = DumpUtcCaptureTime; \n "
" var CurrentDate = Date.now() / 1000; \n "
" var Diff = CurrentDate - DumpDate; \n "
" var Limit = 10*60;//flash old message when loading captures older than 10 minutes \n "
" if(Diff > Limit) \n "
" { \n "
" ShowFlashMessage( \" Captured \" + TimeString(Diff) + \" ago \" , 100); \n "
" } \n "
" if(!nHideHelp) \n "
" { \n "
" ShowHelp(1,0); \n "
" } \n "
" } \n "
" \n "
" function DrawFlashMessage(context) \n "
" { \n "
" if(FlashFrameCounter > 0) \n "
" { \n "
" if(FlashFrameCounter>1) \n "
" { \n "
" var FlashPrc = Math.sin(FlashFrameCounter / FlashFrames); \n "
" context.font = FontFlash; \n "
" context.globalAlpha = FlashPrc * 0.35 + 0.5; \n "
" context.textAlign = \' center \' ; \n "
" context.fillStyle = \' red \' ; \n "
" context.fillText(FlashMessage, nWidth * 0.5, 50); \n "
" context.globalAlpha = 1; \n "
" context.textAlign = \' left \' ; \n "
" context.font = Font; \n "
" } \n "
" FlashFrameCounter -= 1; \n "
" \n "
" } \n "
" } \n "
" \n "
" function DrawCaptureInfo(context) \n "
" { \n "
" context.fillStyle = \' white \' ; \n "
" context.textAlign = \' right \' ; \n "
" context.font = Font; \n "
" var DumpDate = DumpUtcCaptureTime; \n "
" var CurrentDate = Date.now() / 1000; \n "
" var Diff = CurrentDate - DumpDate; \n "
" var DiffString = TimeString(Diff) + \" ago \" ; \n "
" context.fillText(new Date(DumpDate*1000).toLocaleString(), nWidth, FontHeight); \n "
" if(Mode == ModeTimers) \n "
" { \n "
" context.fillText( \" Timer Frames: \" + AggregateInfo.Frames, nWidth, FontHeight*2); \n "
" } \n "
" else \n "
" { \n "
" context.fillText( \" Detailed Frames \" + Frames.length, nWidth, FontHeight*2); \n "
" } \n "
" context.fillText(DumpHost, nWidth, FontHeight*3); \n "
" context.fillText(DiffString, nWidth, FontHeight*4); \n "
" context.textAlign = \' left \' ; \n "
" DrawFlashMessage(context); \n "
" } \n "
" \n "
" function DrawDetailedFrameHistory() \n "
" { \n "
" ProfileEnter( \" DrawDetailedFrameHistory \" ); \n "
" var x = HistoryViewMouseX; \n "
" \n "
" var context = CanvasHistory.getContext( \' 2d \' ); \n "
" context.clearRect(0, 0, CanvasHistory.width, CanvasHistory.height); \n "
" \n "
" var fHeight = nHistoryHeight; \n "
" var fWidth = nWidth / Frames.length; \n "
" var fHeightScale = fHeight / ReferenceTime; \n "
" var fX = 0; \n "
" var FrameIndex = -1; \n "
" var MouseDragging = MouseDragState != MouseDragOff; \n "
" fRangeBeginHistory = fRangeEndHistory = -1; \n "
" fRangeBeginHistoryGpu = fRangeEndHistoryGpu = -1; \n "
" \n "
" var FrameFirst = -1; \n "
" var FrameLast = nWidth; \n "
" var fDetailedOffsetEnd = fDetailedOffset + fDetailedRange; \n "
" for(i = 0; i < Frames.length; i++) \n "
" { \n "
" var fMs = Frames[i].frameend - Frames[i].framestart; \n "
" if(fDetailedOffset <= Frames[i].frameend && fDetailedOffset >= Frames[i].framestart) \n "
" { \n "
" var lerp = (fDetailedOffset - Frames[i].framestart) / (Frames[i].frameend - Frames[i].framestart); \n "
" FrameFirst = fX + fWidth * lerp; \n "
" } \n "
" if(fDetailedOffsetEnd <= Frames[i].frameend && fDetailedOffsetEnd >= Frames[i].framestart) \n "
" { \n "
" var lerp = (fDetailedOffsetEnd - Frames[i].framestart) / (Frames[i].frameend - Frames[i].framestart); \n "
" FrameLast = fX + fWidth * lerp; \n "
" } \n "
" var fH = fHeightScale * fMs; \n "
" var bMouse = x > fX && x < fX + fWidth; \n "
" if(bMouse && !MouseDragging) \n "
" { \n "
" context.fillStyle = FRAME_HISTORY_COLOR_GPU; \n "
" fRangeBeginHistory = Frames[i].framestart; \n "
" fRangeEndHistory = Frames[i].frameend; \n "
" if(Frames[i].framestartgpu) \n "
" { \n "
" fRangeBeginHistoryGpu = Frames[i].framestartgpu; \n "
" fRangeEndHistoryGpu = Frames[i].frameendgpu; \n "
" } \n "
" FrameIndex = i; \n "
" } \n "
" else \n "
" { \n "
" context.fillStyle = FRAME_HISTORY_COLOR_CPU; \n "
" } \n "
" context.fillRect(fX, fHeight - fH, fWidth-1, fH); \n "
" fX += fWidth; \n "
" } \n "
" \n "
" var fRangeHistoryBegin = FrameFirst; \n "
" var fRangeHistoryEnd = FrameLast; \n "
" var X = fRangeHistoryBegin; \n "
" var Y = 0; \n "
" var W = fRangeHistoryEnd - fRangeHistoryBegin; \n "
" context.globalAlpha = 0.35; \n "
" context.fillStyle = \' #009900 \' ; \n "
" context.fillRect(X, Y, W, fHeight); \n "
" context.globalAlpha = 1; \n "
" context.strokeStyle = \' #00ff00 \' ; \n "
" context.beginPath(); \n "
" context.moveTo(X, Y); \n "
" context.lineTo(X, Y+fHeight); \n "
" context.moveTo(X+W, Y); \n "
" context.lineTo(X+W, Y+fHeight); \n "
" context.stroke(); \n "
" \n "
" \n "
" \n "
" \n "
" DrawCaptureInfo(context); \n "
" \n "
" if(FrameIndex>=0 && !MouseDragging) \n "
" { \n "
" var StringArray = []; \n "
" StringArray.push( \" Frame \" ); \n "
" StringArray.push( \" \" + FrameIndex); \n "
" StringArray.push( \" Time \" ); \n "
" StringArray.push( \" \" + (Frames[FrameIndex].frameend - Frames[FrameIndex].framestart).toFixed(3)); \n "
" \n "
" DrawToolTip(StringArray, CanvasHistory, HistoryViewMouseX, HistoryViewMouseY+20); \n "
" \n "
" } \n "
" ProfileLeave(); \n "
" } \n "
" function TimeToMsString(Time) \n "
" { \n "
" return Time.toFixed(3) + \" ms \" ; \n "
" } \n "
" function TimeToString(Time) \n "
" { \n "
" if(Time > 1000) \n "
" { \n "
" return (Time/1000.0).toFixed(0) + \" s \" ; \n "
" } \n "
" else if(Time > 0.9) \n "
" { \n "
" return Time.toFixed(0) + \" ms \" ; \n "
" } \n "
" else if(Time > 0.0009) \n "
" { \n "
" return (Time*1000).toFixed(0) + \" us \" ; \n "
" } \n "
" else \n "
" { \n "
" return (Time*1000000).toFixed(0) + \" ns \" ; \n "
" } \n "
" } \n "
" \n "
" function DrawDetailedBackground(context) \n "
" { \n "
" var fMs = fDetailedRange; \n "
" var fMsEnd = fMs + fDetailedOffset; \n "
" var fMsToScreen = nWidth / fMs; \n "
" var fRate = Math.floor(2*((Math.log(fMs)/Math.log(10))-1))/2; \n "
" var fStep = Math.pow(10, fRate); \n "
" var fRcpStep = 1.0 / fStep; \n "
" var nColorIndex = Math.floor(fDetailedOffset * fRcpStep) % 2; \n "
" if(nColorIndex < 0) \n "
" nColorIndex = -nColorIndex; \n "
" var fStart = Math.floor(fDetailedOffset * fRcpStep) * fStep; \n "
" var fHeight = CanvasDetailedView.height; \n "
" var fScaleX = nWidth / fDetailedRange; \n "
" var HeaderString = TimeToString(fStep); \n "
" context.textAlign = \' center \' ; \n "
" for(f = fStart; f < fMsEnd; ) \n "
" { \n "
" var fNext = f + fStep; \n "
" var X = (f - fDetailedOffset) * fScaleX; \n "
" var W = (fNext-f)*fScaleX; \n "
" context.fillStyle = nBackColors[nColorIndex]; \n "
" context.fillRect(X, 0, W+2, fHeight); \n "
" nColorIndex = 1 - nColorIndex; \n "
" context.fillStyle = \' #777777 \' \n "
" context.fillText(HeaderString, X + W * 0.5, 10); \n "
" context.fillText(HeaderString, X + W * 0.5, nHeight - 10); \n "
" f = fNext; \n "
" } \n "
" context.textAlign = \' left \' ; \n "
" var fScaleX = nWidth / fDetailedRange; \n "
" context.globalAlpha = 0.5; \n "
" context.strokeStyle = \' #bbbbbb \' ; \n "
" context.beginPath(); \n "
" for(var i = 0; i < Frames.length; i++) \n "
" { \n "
" var frfr = Frames[i]; \n "
" if(frfr.frameend < fDetailedOffset || frfr.framestart > fDetailedOffset + fDetailedRange) \n "
" { \n "
" continue; \n "
" } \n "
" var X = (frfr.framestart - fDetailedOffset) * fScaleX; \n "
" if(X >= 0 && X < nWidth) \n "
" { \n "
" context.moveTo(X, 0); \n "
" context.lineTo(X, nHeight); \n "
" } \n "
" } \n "
" context.stroke(); \n "
" context.globalAlpha = 1; \n "
" \n "
" } \n "
" function DrawToolTip(StringArray, Canvas, x, y) \n "
" { \n "
" var context = Canvas.getContext( \' 2d \' ); \n "
" context.font = Font; \n "
" var WidthArray = Array(StringArray.length); \n "
" var nMaxWidth = 0; \n "
" var nHeight = 0; \n "
" for(i = 0; i < StringArray.length; i += 2) \n "
" { \n "
" var nWidth0 = context.measureText(StringArray[i]).width; \n "
" var nWidth1 = context.measureText(StringArray[i+1]).width; \n "
" var nSum = nWidth0 + nWidth1; \n "
" WidthArray[i] = nWidth0; \n "
" WidthArray[i+1] = nWidth1; \n "
" if(nSum > nMaxWidth) \n "
" { \n "
" nMaxWidth = nSum; \n "
" } \n "
" nHeight += BoxHeight; \n "
" } \n "
" nMaxWidth += 15; \n "
" //bounds check. \n "
" var CanvasRect = Canvas.getBoundingClientRect(); \n "
" if(y + nHeight > CanvasRect.height) \n "
" { \n "
" y = CanvasRect.height - nHeight; \n "
" x += 20; \n "
" } \n "
" if(x + nMaxWidth > CanvasRect.width) \n "
" { \n "
" x = CanvasRect.width - nMaxWidth; \n "
" } \n "
" \n "
" context.fillStyle = \' black \' ; \n "
" context.fillRect(x-1, y, nMaxWidth+2, nHeight); \n "
" context.fillStyle = \' white \' ; \n "
" \n "
" var XPos = x; \n "
" var XPosRight = x + nMaxWidth; \n "
" var YPos = y + BoxHeight-2; \n "
" for(i = 0; i < StringArray.length; i += 2) \n "
" { \n "
" context.fillText(StringArray[i], XPos, YPos); \n "
" context.fillText(StringArray[i+1], XPosRight - WidthArray[i+1], YPos); \n "
" YPos += BoxHeight; \n "
" } \n "
" } \n "
" function DrawHoverToolTip() \n "
" { \n "
" ProfileEnter( \" DrawHoverToolTip \" ); \n "
" if(nHoverToken != -1) \n "
" { \n "
" var StringArray = []; \n "
" var groupid = TimerInfo[nHoverToken].group; \n "
" StringArray.push( \" Timer \" ); \n "
" StringArray.push(TimerInfo[nHoverToken].name); \n "
" StringArray.push( \" Group \" ); \n "
" StringArray.push(GroupInfo[groupid].name); \n "
" \n "
" var bShowTimers = Mode == ModeTimers; \n "
" if(FlipToolTip) \n "
" { \n "
" bShowTimers = !bShowTimers; \n "
" } \n "
" if(bShowTimers) \n "
" { \n "
" \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" \" ); \n "
" var Timer = TimerInfo[nHoverToken]; \n "
" StringArray.push( \" Average \" ); \n "
" StringArray.push(Timer.average); \n "
" StringArray.push( \" Max \" ); \n "
" StringArray.push(Timer.max); \n "
" StringArray.push( \" Excl Max \" ); \n "
" StringArray.push(Timer.exclmax); \n "
" StringArray.push( \" Excl Average \" ); \n "
" StringArray.push(Timer.exclaverage); \n "
" StringArray.push( \" Call Average \" ); \n "
" StringArray.push(Timer.callaverage); \n "
" StringArray.push( \" Call Count \" ); \n "
" StringArray.push(Timer.callcount); \n "
" \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" \" ); \n "
" \n "
" \n "
" StringArray.push( \" Group \" ); \n "
" StringArray.push(GroupInfo[groupid].name); \n "
" StringArray.push( \" Average \" ); \n "
" StringArray.push(GroupInfo[groupid].average); \n "
" StringArray.push( \" Max \" ); \n "
" StringArray.push(GroupInfo[groupid].max); \n "
" \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" \" ); \n "
" \n "
" StringArray.push( \" " ;
const size_t g_MicroProfileHtml_end_0_size = sizeof ( g_MicroProfileHtml_end_0 ) ;
const char g_MicroProfileHtml_end_1 [ ] =
" Timer Capture \" ); \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" Frames \" ); \n "
" StringArray.push(AggregateInfo.Frames); \n "
" StringArray.push( \" Time \" ); \n "
" StringArray.push(AggregateInfo.Time.toFixed(2) + \" ms \" ); \n "
" \n "
" \n "
" \n "
" \n "
" } \n "
" else \n "
" { \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" \" ); \n "
" \n "
" \n "
" \n "
" StringArray.push( \" Time \" ); \n "
" StringArray.push((fRangeEnd-fRangeBegin).toFixed(3)); \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" Total \" ); \n "
" StringArray.push( \" \" + TimerInfo[nHoverToken].Sum); \n "
" StringArray.push( \" Max \" ); \n "
" StringArray.push( \" \" + TimerInfo[nHoverToken].Max); \n "
" StringArray.push( \" Average \" ); \n "
" StringArray.push( \" \" + TimerInfo[nHoverToken].Average); \n "
" StringArray.push( \" Count \" ); \n "
" StringArray.push( \" \" + TimerInfo[nHoverToken].CallCount); \n "
" \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" \" ); \n "
" \n "
" StringArray.push( \" Max/Frame \" ); \n "
" StringArray.push( \" \" + TimerInfo[nHoverToken].FrameMax); \n "
" \n "
" StringArray.push( \" Average Time/Frame \" ); \n "
" StringArray.push( \" \" + TimerInfo[nHoverToken].FrameAverage); \n "
" \n "
" StringArray.push( \" Average Count/Frame \" ); \n "
" StringArray.push( \" \" + TimerInfo[nHoverToken].FrameCallAverage); \n "
" \n "
" \n "
" \n "
" \n "
" \n "
" \n "
" if(nHoverFrame != -1) \n "
" { \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" Frame \" + nHoverFrame); \n "
" StringArray.push( \" \" ); \n "
" \n "
" var FrameTime = new Object(); \n "
" CalculateTimers(FrameTime, nHoverToken, nHoverFrame, nHoverFrame+1); \n "
" StringArray.push( \" Total \" ); \n "
" StringArray.push( \" \" + FrameTime.Sum); \n "
" StringArray.push( \" Count \" ); \n "
" StringArray.push( \" \" + FrameTime.CallCount); \n "
" StringArray.push( \" Average \" ); \n "
" StringArray.push( \" \" + FrameTime.Average); \n "
" StringArray.push( \" Max \" ); \n "
" StringArray.push( \" \" + FrameTime.Max); \n "
" } \n "
" \n "
" var HoverInfo = GatherHoverMetaCounters(nHoverToken, nHoverTokenIndex, nHoverTokenLogIndex, nHoverFrame); \n "
" var Header = 0; \n "
" for(index in HoverInfo) \n "
" { \n "
" if(0 == Header) \n "
" { \n "
" Header = 1; \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" Meta \" ); \n "
" StringArray.push( \" \" ); \n "
" \n "
" } \n "
" StringArray.push( \" \" +index); \n "
" StringArray.push( \" \" +HoverInfo[index]); \n "
" } \n "
" \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" \" ); \n "
" \n "
" StringArray.push( \" Detailed Capture \" ); \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" Frames \" ); \n "
" StringArray.push(Frames.length); \n "
" StringArray.push( \" Time \" ); \n "
" StringArray.push(DetailedTotal().toFixed(2) + \" ms \" ); \n "
" \n "
" \n "
" } \n "
" DrawToolTip(StringArray, CanvasDetailedView, DetailedViewMouseX, DetailedViewMouseY+20); \n "
" } \n "
" else if(nHoverCSCpu >= 0) \n "
" { \n "
" var StringArray = []; \n "
" StringArray.push( \" Context Switch \" ); \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" \" ); \n "
" StringArray.push( \" Cpu \" ); \n "
" StringArray.push( \" \" + nHoverCSCpu); \n "
" StringArray.push( \" Begin \" ); \n "
" StringArray.push( \" \" + fRangeBegin); \n "
" StringArray.push( \" End \" ); \n "
" StringArray.push( \" \" + fRangeEnd); \n "
" DrawToolTip(StringArray, CanvasDetailedView, DetailedViewMouseX, DetailedViewMouseY+20); \n "
" } \n "
" ProfileLeave(); \n "
" } \n "
" \n "
" function FormatMeta(Value, Dec) \n "
" { \n "
" if(!Value) \n "
" { \n "
" Value = \" 0 \" ; \n "
" } \n "
" else \n "
" { \n "
" Value = \' \' + Value.toFixed(Dec); \n "
" } \n "
" return Value; \n "
" } \n "
" \n "
" function DrawBarView() \n "
" { \n "
" ProfileEnter( \" DrawBarView \" ); \n "
" Invalidate++; \n "
" nHoverToken = -1; \n "
" nHoverFrame = -1; \n "
" var context = CanvasDetailedView.getContext( \' 2d \' ); \n "
" context.clearRect(0, 0, nWidth, nHeight); \n "
" \n "
" var Height = BoxHeight; \n "
" var Width = nWidth; \n "
" \n "
" //clamp offset to prevent scrolling into the void \n "
" var nTotalRows = 0; \n "
" for(var groupid in GroupInfo) \n "
" { \n "
" if(GroupsAllActive || GroupsActive[GroupInfo[groupid].name]) \n "
" { \n "
" nTotalRows += GroupInfo[groupid].TimerArray.length + 1; \n "
" } \n "
" } \n "
" var nTotalRowPixels = nTotalRows * Height; \n "
" var nFrameRows = nHeight - BoxHeight; \n "
" if(nOffsetBarsY + nFrameRows > nTotalRowPixels && nTotalRowPixels > nFrameRows) \n "
" { \n "
" nOffsetBarsY = nTotalRowPixels - nFrameRows; \n "
" } \n "
" \n "
" \n "
" var Y = -nOffsetBarsY + BoxHeight; \n "
" if(TimersGroups) \n "
" { \n "
" nOffsetBarsX = 0; \n "
" } \n "
" var XBase = -nOffsetBarsX; \n "
" var nColorIndex = 0; \n "
" \n "
" context.fillStyle = \' white \' ; \n "
" context.font = Font; \n "
" var bMouseIn = 0; \n "
" var RcpReferenceTime = 1.0 / ReferenceTime; \n "
" var CountWidth = 8 * FontWidth; \n "
" var nMetaLen = TimerInfo[0].meta.length; \n "
" var nMetaCharacters = 10; \n "
" for(var i = 0; i < nMetaLen; ++i) \n "
" { \n "
" if(nMetaCharacters < MetaNames[i].length) \n "
" nMetaCharacters = MetaNames[i].length; \n "
" } \n "
" var nWidthMeta = nMetaCharacters * FontWidth + 6; \n "
" function DrawHeaderSplit(Header) \n "
" { \n "
" context.fillStyle = \' white \' ; \n "
" context.fillText(Header, X, Height-FontAscent); \n "
" X += nWidthBars; \n "
" context.fillStyle = nBackColorOffset; \n "
" X += nWidthMs; \n "
" if(X >= NameWidth) \n "
" { \n "
" context.fillRect(X-3, 0, 1, nHeight); \n "
" } \n "
" } \n "
" function DrawHeaderSplitSingle(Header, Width) \n "
" { \n "
" context.fillStyle = \' white \' ; \n "
" context.fillText(Header, X, Height-FontAscent); \n "
" X += Width; \n "
" context.fillStyle = nBackColorOffset; \n "
" if(X >= NameWidth) \n "
" { \n "
" context.fillRect(X-3, 0, 1, nHeight); \n "
" } \n "
" } \n "
" function DrawHeaderSplitLeftRight(HeaderLeft, HeaderRight, Width) \n "
" { \n "
" context.textAlign = \' left \' ; \n "
" context.fillStyle = \' white \' ; \n "
" context.fillText(HeaderLeft, X, Height-FontAscent); \n "
" X += Width; \n "
" context.textAlign = \' right \' ; \n "
" context.fillText(HeaderRight, X-5, Height-FontAscent); \n "
" context.textAlign = \' left \' ; \n "
" context.fillStyle = nBackColorOffset; \n "
" if(X >= NameWidth) \n "
" { \n "
" context.fillRect(X-3, 0, 1, nHeight); \n "
" } \n "
" } \n "
" function DrawTimer(Value, Color) \n "
" { \n "
" var Prc = Value * RcpReferenceTime; \n "
" var YText = Y+Height-FontAscent; \n "
" if(Prc > 1) \n "
" { \n "
" Prc = 1; \n "
" } \n "
" context.fillStyle = Color; \n "
" context.fillRect(X+1, Y+1, Prc * nBarsWidth, InnerBoxHeight); \n "
" X += nWidthBars; \n "
" context.fillStyle = \' white \' ; \n "
" context.fillText(( \" \" + Value.toFixed(2)).slice(-TimerLen), X, YText); \n "
" X += nWidthMs; \n "
" } \n "
" function DrawMeta(Value, Width, Dec) \n "
" { \n "
" Value = FormatMeta(Value, Dec); \n "
" X += (FontWidth*Width); \n "
" context.textAlign = \' right \' ; \n "
" context.fillText(Value, X-FontWidth, YText); \n "
" context.textAlign = \' left \' ; \n "
" } \n "
" var InnerBoxHeight = BoxHeight-2; \n "
" var TimerLen = 6; \n "
" var TimerWidth = TimerLen * FontWidth; \n "
" var nWidthBars = nBarsWidth+2; \n "
" var nWidthMs = TimerWidth+2+10; \n "
" \n "
" \n "
" if(2 == TimersGroups) \n "
" { \n "
" for(var i = 0; i < ThreadNames.length; ++i) \n "
" { \n "
" if(ThreadsActive[ThreadNames[i]] || ThreadsAllActive) \n "
" { \n "
" var X = 0; \n "
" var YText = Y+Height-FontAscent; \n "
" bMouseIn = DetailedViewMouseY >= Y && DetailedViewMouseY < Y + BoxHeight; \n "
" nColorIndex = 1-nColorIndex; \n "
" context.fillStyle = bMouseIn ? nBackColorOffset : nBackColors[nColorIndex]; \n "
" context.fillRect(0, Y, Width, Height); \n "
" var ThreadColor = CSwitchColors[i % CSwitchColors.length]; \n "
" context.fillStyle = ThreadColor; \n "
" context.fillText(ThreadNames[i], 1, YText); \n "
" context.textAlign = \' left \' ; \n "
" Y += Height; \n "
" for(var idx in GroupOrder) \n "
" { \n "
" var groupid = GroupOrder[idx]; \n "
" var Group = GroupInfo[groupid]; \n "
" var PerThreadTimer = ThreadGroupTimeArray[i][groupid]; \n "
" var PerThreadTimerTotal = ThreadGroupTimeTotalArray[i][groupid]; \n "
" if((PerThreadTimer > 0.0001|| PerThreadTimerTotal>0.1) && (GroupsAllActive || GroupsActive[Group.name])) \n "
" { \n "
" var GColor = GroupColors ? GroupInfo[groupid].color : \' white \' ; \n "
" var X = 0; \n "
" nColorIndex = 1-nColorIndex; \n "
" bMouseIn = DetailedViewMouseY >= Y && DetailedViewMouseY < Y + BoxHeight; \n "
" context.fillStyle = bMouseIn ? nBackColorOffset : nBackColors[nColorIndex]; \n "
" context.fillRect(0, Y, Width, nHeight); \n "
" context.fillStyle = GColor; \n "
" context.textAlign = \' right \' ; \n "
" context.fillText(Group.name, NameWidth - 5, Y+Height-FontAscent); \n "
" context.textAlign = \' left \' ; \n "
" X += NameWidth; \n "
" DrawTimer(PerThreadTimer, GColor); \n "
" X += nWidthBars + nWidthMs; \n "
" DrawTimer(PerThreadTimerTotal, GColor); \n "
" \n "
" Y += Height; \n "
" } \n "
" } \n "
" } \n "
" } \n "
" } \n "
" else \n "
" { \n "
" for(var idx in GroupOrder) \n "
" { \n "
" var groupid = GroupOrder[idx]; \n "
" var Group = GroupInfo[groupid]; \n "
" var GColor = GroupColors ? GroupInfo[groupid].color : \' white \' ; \n "
" if(GroupsAllActive || GroupsActive[Group.name]) \n "
" { \n "
" var TimerArray = Group.TimerArray; \n "
" var X = XBase; \n "
" nColorIndex = 1-nColorIndex; \n "
" bMouseIn = DetailedViewMouseY >= Y && DetailedViewMouseY < Y + BoxHeight; \n "
" context.fillStyle = bMouseIn ? nBackColorOffset : nBackColors[nColorIndex]; \n "
" context.fillRect(0, Y, Width, nHeight); \n "
" context.fillStyle = GColor; \n "
" context.fillText(Group.name, 1, Y+Height-FontAscent); \n "
" X += NameWidth; \n "
" DrawTimer(Group.average, GColor); \n "
" DrawTimer(Group.max, GColor); \n "
" DrawTimer(Group.total, GColor); \n "
" \n "
" context.fillStyle = bMouseIn ? nBackColorOffset : nBackColors[nColorIndex]; \n "
" context.fillRect(0, Y, NameWidth, nHeight); \n "
" context.fillStyle = GColor; \n "
" context.fillText(Group.name, 1, Y+Height-FontAscent); \n "
" \n "
" \n "
" \n "
" Y += Height; \n "
" if(TimersGroups) \n "
" { \n "
" for(var i = 0; i < ThreadNames.length; ++i) \n "
" { \n "
" var PerThreadTimer = ThreadGroupTimeArray[i][groupid]; \n "
" var PerThreadTimerTotal = ThreadGroupTimeTotalArray[i][groupid]; \n "
" if((PerThreadTimer > 0.0001|| PerThreadTimerTotal>0.1) && (ThreadsActive[ThreadNames[i]] || ThreadsAllActive)) \n "
" { \n "
" var YText = Y+Height-FontAscent; \n "
" bMouseIn = DetailedViewMouseY >= Y && DetailedViewMouseY < Y + BoxHeight; \n "
" nColorIndex = 1-nColorIndex; \n "
" context.fillStyle = bMouseIn ? nBackColorOffset : nBackColors[nColorIndex]; \n "
" context.fillRect(0, Y, Width, Height); \n "
" var ThreadColor = CSwitchColors[i % CSwitchColors.length]; \n "
" context.fillStyle = ThreadColor; \n "
" context.textAlign = \' right \' ; \n "
" context.fillText(ThreadNames[i], NameWidth - 5, YText); \n "
" context.textAlign = \' left \' ; \n "
" X = NameWidth; \n "
" DrawTimer(PerThreadTimer, ThreadColor); \n "
" X += nWidthBars + nWidthMs; \n "
" DrawTimer(PerThreadTimerTotal, ThreadColor); \n "
" Y += Height; \n "
" } \n "
" } \n "
" } \n "
" else \n "
" { \n "
" for(var timerindex in TimerArray) \n "
" { \n "
" var timerid = TimerArray[timerindex]; \n "
" var Timer = TimerInfo[timerid]; \n "
" var Average = Timer.average; \n "
" var Max = Timer.max; \n "
" var ExclusiveMax = Timer.exclmax; \n "
" var ExclusiveAverage = Timer.exclaverage; \n "
" var CallAverage = Timer.callaverage; \n "
" var CallCount = Timer.callcount; \n "
" var YText = Y+Height-FontAscent; \n "
" X = NameWidth + XBase; \n "
" \n "
" nColorIndex = 1-nColorIndex; \n "
" bMouseIn = DetailedViewMouseY >= Y && DetailedViewMouseY < Y + BoxHeight; \n "
" if(bMouseIn) \n "
" { \n "
" nHoverToken = timerid; \n "
" } \n "
" context.fillStyle = bMouseIn ? nBackColorOffset : nBackColors[nColorIndex]; \n "
" context.fillRect(0, Y, Width, Height); \n "
" \n "
" DrawTimer(Average, Timer.color); \n "
" DrawTimer(Max,Timer.color); \n "
" DrawTimer(Timer.total,Timer.color); \n "
" DrawTimer(CallAverage,Timer.color); \n "
" context.fillStyle = \' white \' ; \n "
" context.fillText(CallCount, X, YText); \n "
" X += CountWidth; \n "
" DrawTimer(ExclusiveAverage,Timer.color); \n "
" DrawTimer(ExclusiveMax,Timer.color); \n "
" \n "
" if(TimersMeta) \n "
" { \n "
" context.fillStyle = \' white \' ; \n "
" for(var j = 0; j < nMetaLen; ++j) \n "
" { \n "
" // var Len = MetaNames[j].length + 1; \n "
" DrawMeta(Timer.meta[j], MetaLengths[j], 0); \n "
" DrawMeta(Timer.metaavg[j], MetaLengthsAvg[j], 2); \n "
" DrawMeta(Timer.metamax[j], MetaLengthsMax[j], 0); \n "
" } \n "
" } \n "
" context.fillStyle = bMouseIn ? nBackColorOffset : nBackColors[nColorIndex]; \n "
" context.fillRect(0, Y, NameWidth, Height); \n "
" context.textAlign = \' right \' ; \n "
" context.fillStyle = Timer.color; \n "
" context.fillText(Timer.name, NameWidth - 5, YText); \n "
" context.textAlign = \' left \' ; \n "
" \n "
" \n "
" Y += Height; \n "
" } \n "
" } \n "
" } \n "
" } \n "
" } \n "
" X = 0; \n "
" context.fillStyle = nBackColorOffset; \n "
" context.fillRect(0, 0, Width, Height); \n "
" context.fillStyle = \' white \' ; \n "
" if(TimersGroups) \n "
" { \n "
" if(2 == TimersGroups) \n "
" { \n "
" DrawHeaderSplitLeftRight( \' Thread \' , \' Group \' , NameWidth); \n "
" DrawHeaderSplit( \' Average \' ); \n "
" } \n "
" else \n "
" { \n "
" DrawHeaderSplitLeftRight( \' Group \' , \' Thread \' , NameWidth); \n "
" DrawHeaderSplit( \' Average \' ); \n "
" DrawHeaderSplit( \' Max \' ); \n "
" DrawHeaderSplit( \' Total \' ); \n "
" } \n "
" } \n "
" else \n "
" { \n "
" X = NameWidth + XBase; \n "
" DrawHeaderSplit( \' Average \' ); \n "
" DrawHeaderSplit( \' Max \' ); \n "
" DrawHeaderSplit( \' Total \' ); \n "
" DrawHeaderSplit( \' Call Average \' ); \n "
" DrawHeaderSplitSingle( \' Count \' , CountWidth); \n "
" DrawHeaderSplit( \' Excl Average \' ); \n "
" DrawHeaderSplit( \' Excl Max \' ); \n "
" if(TimersMeta) \n "
" { \n "
" for(var i = 0; i < nMetaLen; ++i) \n "
" { \n "
" DrawHeaderSplitSingle(MetaNames[i], MetaLengths[i] * FontWidth); \n "
" DrawHeaderSplitSingle(MetaNames[i] + \" Avg \" , MetaLengthsAvg[i] * FontWidth); \n "
" DrawHeaderSplitSingle(MetaNames[i] + \" Max \" , MetaLengthsMax[i] * FontWidth); \n "
" } \n "
" } \n "
" X = 0; \n "
" context.fillStyle = nBackColorOffset; \n "
" context.fillRect(0, 0, NameWidth, Height); \n "
" context.fillStyle = \' white \' ; \n "
" \n "
" DrawHeaderSplitLeftRight( \' Group \' , \' Timer \' , NameWidth); \n "
" \n "
" } \n "
" \n "
" ProfileLeave(); \n "
" } \n "
" \n "
" \n "
" //preprocess context switch data to contain array per thread \n "
" function PreprocessContextSwitchCacheItem(ThreadId) \n "
" { \n "
" console.log( \' context switch preparing \' + ThreadId); \n "
" var CSObject = CSwitchCache[ThreadId]; \n "
" if(ThreadId > 0 && !CSObject) \n "
" { \n "
" CSArrayIn = new Array(); \n "
" CSArrayOut = new Array(); \n "
" CSArrayCpu = new Array(); \n "
" var nCount = CSwitchTime.length; \n "
" var j = 0; \n "
" var TimeIn = -1.0; \n "
" for(var i = 0; i < nCount; ++i) \n "
" { \n "
" var ThreadIn = CSwitchThreadInOutCpu[j]; \n "
" var ThreadOut = CSwitchThreadInOutCpu[j+1]; \n "
" var Cpu = CSwitchThreadInOutCpu[j+2]; \n "
" if(TimeIn < 0) \n "
" { \n "
" if(ThreadIn == ThreadId) \n "
" { \n "
" TimeIn = CSwitchTime[i]; \n "
" } \n "
" } \n "
" else \n "
" { \n "
" if(ThreadOut == ThreadId) \n "
" { \n "
" var TimeOut = CSwitchTime[i]; \n "
" CSArrayIn.push(TimeIn); \n "
" CSArrayOut.push(TimeOut); \n "
" CSArrayCpu.push(Cpu); \n "
" TimeIn = -1; \n "
" } \n "
" } \n "
" j += 3; \n "
" } \n "
" CSObject = new Object(); \n "
" CSObject.Size = CSArrayIn.length; \n "
" CSObject.In = CSArrayIn; \n "
" CSObject.Out = CSArrayOut; \n "
" CSObject.Cpu = CSArrayCpu; \n "
" CSwitchCache[ThreadId] = CSObject; \n "
" } \n "
" \n "
" } \n "
" function PreprocessContextSwitchCache() \n "
" { \n "
" ProfileEnter( \" PreprocessContextSwitchCache \" ); \n "
" var AllThreads = {}; \n "
" var nCount = CSwitchTime.length; \n "
" for(var i = 0; i < nCount; ++i) \n "
" { \n "
" var nThreadIn = CSwitchThreadInOutCpu[i]; \n "
" if(!AllThreads[nThreadIn]) \n "
" { \n "
" AllThreads[nThreadIn] = \' \' + nThreadIn; \n "
" var FoundThread = false; \n "
" for(var i = 0; i < ThreadIds.length; ++i) \n "
" { \n "
" if(ThreadIds[i] == nThreadIn) \n "
" { \n "
" FoundThread = true; \n "
" } \n "
" } \n "
" if(!FoundThread) \n "
" { \n "
" CSwitchOnlyThreads.push(nThreadIn); \n "
" } \n "
" } \n "
" } \n "
" for(var i = 0; i < CSwitchOnlyThreads.length; ++i) \n "
" { \n "
" PreprocessContextSwitchCacheItem(CSwitchOnlyThreads[i]); \n "
" } \n "
" for(var i = 0; i < ThreadIds.length; ++i) \n "
" { \n "
" PreprocessContextSwitchCacheItem(ThreadIds[i]); \n "
" } \n "
" ProfileLeave(); \n "
" } \n "
" \n "
" function DrawContextSwitchBars(context, ThreadId, fScaleX, fOffsetY, fDetailedOffset, nHoverColor, MinWidth, bDrawEnabled) \n "
" { \n "
" ProfileEnter( \" DrawContextSwitchBars \" ); \n "
" var CSObject = CSwitchCache[ThreadId]; \n "
" if(CSObject) \n "
" { \n "
" var Size = CSObject.Size; \n "
" var In = CSObject.In; \n "
" var Out = CSObject.Out; \n "
" var Cpu = CSObject.Cpu; \n "
" var nNumColors = CSwitchColors.length; \n "
" for(var i = 0; i < Size; ++i) \n "
" { \n "
" var TimeIn = In[i]; \n "
" var TimeOut = Out[i]; \n "
" var ActiveCpu = Cpu[i]; \n "
" \n "
" var X = (TimeIn - fDetailedOffset) * fScaleX; \n "
" if(X > nWidth) \n "
" { \n "
" break; \n "
" } \n "
" var W = (TimeOut - TimeIn) * fScaleX; \n "
" if(W > MinWidth && X+W > 0) \n "
" { \n "
" if(nHoverCSCpu == ActiveCpu || bDrawEnabled) \n "
" { \n "
" if(nHoverCSCpu == ActiveCpu) \n "
" { \n "
" context.fillStyle = nHoverColor; \n "
" } \n "
" else \n "
" { \n "
" context.fillStyle = CSwitchColors[ActiveCpu % nNumColors]; \n "
" } \n "
" context.fillRect(X, fOffsetY, W, CSwitchHeight); \n "
" } \n "
" if(DetailedViewMouseX >= X && DetailedViewMouseX <= X+W && DetailedViewMouseY < fOffsetY+CSwitchHeight && DetailedViewMouseY >= fOffsetY) \n "
" { \n "
" nHoverCSCpuNext = ActiveCpu; \n "
" fRangeBeginNext = TimeIn; \n "
" fRangeEndNext = TimeOut; \n "
" fRangeBeginGpuNext = fRangeEndGpuNext = -1; \n "
" } \n "
" } \n "
" } \n "
" } \n "
" ProfileLeave(); \n "
" } \n "
" \n "
" function DrawDetailedView(context, MinWidth, bDrawEnabled) \n "
" { \n "
" if(bDrawEnabled) \n "
" { \n "
" DrawDetailedBackground(context); \n "
" } \n "
" \n "
" var colors = [ \' #ff0000 \' , \' #ff00ff \' , \' #ffff00 \' ]; \n "
" \n "
" var fScaleX = nWidth / fDetailedRange; \n "
" var fOffsetY = -nOffsetY + BoxHeight; \n "
" nHoverTokenNext = -1; \n "
" nHoverTokenLogIndexNext = -1; \n "
" nHoverTokenIndexNext = -1; \n "
" nHoverCounter += nHoverCounterDelta; \n "
" if(nHoverCounter >= 255) \n "
" { \n "
" nHoverCounter = 255; \n "
" nHoverCounterDelta = -nHoverCounterDelta; \n "
" } \n "
" if(nHoverCounter < 128) \n "
" { \n "
" nHoverCounter = 128; \n "
" nHoverCounterDelta = -nHoverCounterDelta; \n "
" } \n "
" var nHoverHigh = nHoverCounter.toString(16); \n "
" var nHoverLow = (127+255-nHoverCounter).toString(16); \n "
" var nHoverColor = \' # \' + nHoverHigh + nHoverHigh + nHoverHigh; \n "
" \n "
" context.fillStyle = \' black \' ; \n "
" context.font = Font; \n "
" var nNumLogs = Frames[0].ts.length; \n "
" var fTimeEnd = fDetailedOffset + fDetailedRange; \n "
" \n "
" var FirstFrame = 0; \n "
" for(var i = 0; i < Frames.length ; i++) \n "
" { \n "
" if(Frames[i].frameend < fDetailedOffset) \n "
" { \n "
" FirstFrame = i; \n "
" } \n "
" } \n "
" var nMinTimeMs = MinWidth / fScaleX; \n "
" { \n "
" \n "
" var Batches = new Array(TimerInfo.length); \n "
" var BatchesTxt = Array(); \n "
" var BatchesTxtPos = Array(); \n "
" var BatchesTxtColor = [ \' #ffffff \' , \' #333333 \' ]; \n "
" \n "
" for(var i = 0; i < 2; ++i) \n "
" { \n "
" BatchesTxt[i] = Array(); \n "
" BatchesTxtPos[i] = Array(); \n "
" } \n "
" for(var i = 0; i < Batches.length; ++i) \n "
" { \n "
" Batches[i] = Array(); \n "
" } \n "
" for(nLog = 0; nLog < nNumLogs; nLog++) \n "
" { \n "
" var ThreadName = ThreadNames[nLog]; \n "
" if(ThreadsAllActive || ThreadsActive[ThreadName]) \n "
" { \n "
" \n "
" var LodIndex = 0; \n "
" var MinDelta = 0; \n "
" var NextLod = 1; \n "
" while(NextLod < LodData.length && LodData[NextLod].MinDelta[nLog] < nMinTimeMs) \n "
" { \n "
" LodIndex = NextLod; \n "
" NextLod = NextLod + 1; \n "
" MinDelta = LodData[LodIndex].MinDelta[nLog]; \n "
" } \n "
" if(LodIndex == LodData.length) \n "
" { \n "
" LodIndex = LodData.length-1; \n "
" } \n "
" if(DisableLod) \n "
" { \n "
" LodIndex = 0; \n "
" } \n "
" \n "
" context.fillStyle = \' white \' ; \n "
" fOffsetY += BoxHeight; \n "
" context.fillText(ThreadName, 0, fOffsetY); \n "
" if(nContextSwitchEnabled) \n "
" { \n "
" DrawContextSwitchBars(context, ThreadIds[nLog], fScaleX, fOffsetY, fDetailedOffset, nHoverColor, MinWidth, bDrawEnabled); \n "
" fOffsetY += CSwitchHeight+1; \n "
" } \n "
" var MaxDepth = 1; \n "
" var StackPos = 0; \n "
" var Stack = Array(20); \n "
" var Lod = LodData[LodIndex]; \n "
" \n "
" var TypeArray = Lod.TypeArray[nLog]; \n "
" var IndexArray = Lod.IndexArray[nLog]; \n "
" var TimeArray = Lod.TimeArray[nLog]; \n "
" \n "
" var LocalFirstFrame = Frames[FirstFrame].FirstFrameIndex[nLog]; \n "
" var IndexStart = Lod.LogStart[LocalFirstFrame][nLog]; \n "
" var IndexEnd = TimeArray.length; \n "
" IndexEnd = TimeArray.length; \n "
" var HasSetHover = 0; \n "
" \n "
" \n "
" for(var j = IndexStart; j < IndexEnd; ++j) \n "
" { \n "
" var type = TypeArray[j]; \n "
" var index = IndexArray[j]; \n "
" var time = TimeArray[j]; \n "
" if(type == 1) \n "
" { \n "
" //push \n "
" Stack[StackPos] = j; \n "
" StackPos++; \n "
" if(StackPos > MaxDepth) \n "
" { \n "
" MaxDepth = StackPos; \n "
" } \n "
" } \n "
" else if(type == 0) \n "
" { \n "
" if(StackPos>0) \n "
" { \n "
" StackPos--; \n "
" \n "
" var StartIndex = Stack[StackPos]; \n "
" var timestart = TimeArray[StartIndex]; \n "
" var timeend = time; \n "
" var X = (timestart - fDetailedOffset) * fScaleX; \n "
" var Y = fOffsetY + StackPos * BoxHeight; \n "
" var W = (timeend-timestart)*fScaleX; \n "
" \n "
" if(W > MinWidth && X < nWidth && X+W > 0) \n "
" { \n "
" if(bDrawEnabled || index == nHoverToken) \n "
" { \n "
" Batches[index].push(X); \n "
" Batches[index].push(Y); \n "
" Batches[index].push(W); \n "
" DebugDrawQuadCount++; \n "
" \n "
" var XText = X < 0 ? 0 : X; \n "
" var WText = W - (XText-X); \n "
" if(XText + WText > nWidth) \n "
" { \n "
" WText = nWidth - XText; \n "
" } \n "
" var Name = TimerInfo[index].name; \n "
" var NameLen = TimerInfo[index].len; \n "
" var BarTextLen = Math.floor((WText-2)/FontWidth); \n "
" var TimeText = TimeToMsString(timeend-timestart); \n "
" var TimeTextLen = TimeText.length; \n "
" \n "
" if(BarTextLen >= 2) \n "
" { \n "
" if(BarTextLen < NameLen) \n "
" Name = Name.substr(0, BarTextLen); \n "
" var txtidx = TimerInfo[index].textcolorindex; \n "
" var YPos = Y+BoxHeight-FontAscent; \n "
" BatchesTxt[txtidx].push(Name); \n "
" BatchesTxtPos[txtidx].push(XText+2); \n "
" \n "
" BatchesTxtPos[txtidx].push(YPos); \n "
" DebugDrawTextCount++; \n "
" if(BarTextLen - NameLen > TimeTextLen) \n "
" { \n "
" BatchesTxt[txtidx].push(TimeText); \n "
" BatchesTxtPos[txtidx].push(XText+WText-2 - TimeTextLen * FontWidth); \n "
" BatchesTxtPos[txtidx].push(YPos); \n "
" DebugDrawTextCount++; \n "
" } \n "
" \n "
" } \n "
" } \n "
" \n "
" if(DetailedViewMouseX >= X && DetailedViewMouseX <= X+W && DetailedViewMouseY < Y+BoxHeight && DetailedViewMouseY >= Y) \n "
" { \n "
" fRangeBeginNext = timestart; \n "
" fRangeEndNext = timeend; \n "
" if(TypeArray[StartIndex+1] == 3 && TypeArray[j+1] == 3) \n "
" { \n "
" fRangeBeginGpuNext = fRangeBeginNext; \n "
" fRangeEndGpuNext = fRangeEndNext; \n "
" //cpu tick is stored following \n "
" fRangeBeginNext = TimeArray[StartIndex+1]; \n "
" fRangeEndNext = TimeArray[j+1]; \n "
" } \n "
" else \n "
" { \n "
" fRangeBeginGpuNext = -1; \n "
" fRangeEndGpuNext = -1; \n "
" } \n "
" \n "
" nHoverTokenNext = index; \n "
" nHoverTokenIndexNext = j; \n "
" nHoverTokenLogIndexNext = nLog; \n "
" bHasSetHover = 1; \n "
" } \n "
" } \n "
" if(StackPos == 0 && time > fTimeEnd) \n "
" break; \n "
" } \n "
" } \n "
" } \n "
" fOffsetY += (1+g_MaxStack[nLog]) * BoxHeight; \n "
" \n "
" if(HasSetHover) \n "
" { \n "
" for(var i = 0; i < Frames.length-1; ++i) \n "
" { \n "
" var IndexStart = Lod.LogStart[i][nLog]; \n "
" if(nHoverTokenNext >= IndexStart) \n "
" { \n "
" nHoverFrame = i; \n "
" } \n "
" } \n "
" } \n "
" } \n "
" } \n "
" \n "
" if(nContextSwitchEnabled) //non instrumented threads. \n "
" { \n "
" var ContextSwitchThreads = CSwitchOnlyThreads; \n "
" for(var i = 0; i < ContextSwitchThreads.length; ++i) \n "
" { \n "
" var ThreadId = ContextSwitchThreads[i]; \n "
" var ThreadName = \' \' + ThreadId; \n "
" DrawContextSwitchBars(context, ThreadId, fScaleX, fOffsetY, fDetailedOffset, nHoverColor, MinWidth, bDrawEnabled); \n "
" context.fillStyle = \' white \' ; \n "
" context.fillText(ThreadName, 0, fOffsetY+5); \n "
" fOffsetY += BoxHeight + 1; \n "
" } \n "
" } \n "
" \n "
" \n "
" { \n "
" for(var i = 0; i < Batches.length; ++i) \n "
" { \n "
" var a = Batches[i]; \n "
" if(a.length) \n "
" { \n "
" context.fillStyle = TimerInfo[i].colordark; \n "
" if(!DisableMerge) \n "
" { \n "
" for(var j = 0; j < a.length; j += 3) \n "
" { \n "
" var X = a[j]; \n "
" var Y = a[j+1]; \n "
" var BaseWidth = j + 2; \n "
" var W = a[BaseWidth]; \n "
" while(j+1 < a.length && W < 1) \n "
" { \n "
" var jnext = j+3; \n "
" var XNext = a[jnext]; \n "
" var YNext = a[jnext+1]; \n "
" var WNext = a[jnext+2]; \n "
" var Delta = XNext - (X+W); \n "
" var YDelta = Math.abs(Y - YNext); \n "
" if(Delta < 0.3 && YDelta < 0.5 && WNext < 1) \n "
" { \n "
" W = (XNext+WNext) - X; \n "
" a[BaseWidth] = W; \n "
" a[jnext+2] = 0; \n "
" j += 3; \n "
" } \n "
" else \n "
" { \n "
" break; \n "
" } \n "
" \n "
" } \n "
" } \n "
" } \n "
" var off = 0.7; \n "
" var off2 = 2*off; \n "
" context.fillStyle = TimerInfo[i].colordark; \n "
" for(var j = 0; j < a.length; j += 3) \n "
" { \n "
" var X = a[j]; \n "
" var Y = a[j+1]; \n "
" var W = a[j+2]; \n "
" if(W >= 1) \n "
" { \n "
" context.fillRect(X, Y, W, BoxHeight-1); \n "
" } \n "
" } \n "
" \n "
" \n "
" if(i == nHoverToken) \n "
" { \n "
" context.fillStyle = nHoverColor; \n "
" } \n "
" else \n "
" { \n "
" context.fillStyle = TimerInfo[i].color; \n "
" } \n "
" for(var j = 0; j < a.length; j += 3) \n "
" { \n "
" var X = a[j]; \n "
" var Y = a[j+1]; \n "
" var W = a[j+2]; \n "
" if(W > 0) \n "
" { \n "
" context.fillRect(X+off, Y+off, W-off2, BoxHeight-1-off2); \n "
" } \n "
" } \n "
" } \n "
" } \n "
" } \n "
" for(var i = 0; i < BatchesTxt.length; ++i) \n "
" { \n "
" context.fillStyle = BatchesTxtColor[i]; \n "
" var TxtArray = BatchesTxt[i]; \n "
" var PosArray = BatchesTxtPos[i]; \n "
" for(var j = 0; j < TxtArray.length; ++j) \n "
" { \n "
" var k = j * 2; \n "
" context.fillText(TxtArray[j], PosArray[k],PosArray[k+1]); \n "
" } \n "
" } \n "
" \n "
" } \n "
" } \n "
" function DrawTextBox(context, text, x, y, align) \n "
" { \n "
" var textsize = context.measureText(text).width; \n "
" var offsetx = 0; \n "
" var offsety = -FontHeight; \n "
" if(align == \' center \' ) \n "
" { \n "
" offsetx = -textsize / 2.0; \n "
" } \n "
" else if(align == \' right \' ) \n "
" { \n "
" offsetx = -textsize; \n "
" } \n "
" context.fillStyle = nBackColors[0]; \n "
" context.fillRect(x + offsetx, y + offsety, textsize+2, FontHeight + 2); \n "
" context.fillStyle = \' white \' ; \n "
" context.fillText(text, x, y); \n "
" \n "
" } \n "
" function DrawRange(context, fBegin, fEnd, ColorBack, ColorFront, Offset, Name) \n "
" { \n "
" if(fBegin < fEnd) \n "
" { \n "
" var fScaleX = nWidth / fDetailedRange; \n "
" var X = (fBegin - fDetailedOffset) * fScaleX; \n "
" var YSpace = (FontHeight+2); \n "
" var Y = YSpace * (Offset); \n "
" var W = (fEnd - fBegin) * fScaleX; \n "
" context.globalAlpha = 0.1; \n "
" context.fillStyle = ColorBack; \n "
" context.fillRect(X, 0, W, nHeight); \n "
" context.globalAlpha = 1; \n "
" context.strokeStyle = ColorFront; \n "
" context.beginPath(); \n "
" context.moveTo(X, 0); \n "
" context.lineTo(X, nHeight); \n "
" context.moveTo(X+W, 0); \n "
" context.lineTo(X+W, nHeight); \n "
" context.stroke(); \n "
" var Duration = (fEnd - fBegin).toFixed(2) + \" ms \" ; \n "
" var Center = ((fBegin + fEnd) / 2.0) - fDetailedOffset; \n "
" var DurationWidth = context.measureText(Duration+ \" \" ).width; \n "
" \n "
" context.fillStyle = \' white \' ; \n "
" context.textAlign = \' right \' ; \n "
" var TextPosY = Y + YSpace; \n "
" DrawTextBox(context, \' \' + fBegin.toFixed(2), X-3, TextPosY, \' right \' ); \n "
" if(DurationWidth < W + 10) \n "
" { \n "
" context.textAlign = \' center \' ; \n "
" DrawTextBox(context, \' \' + Duration,Center * fScaleX, TextPosY, \' center \' ); \n "
" \n "
" var W0 = W - DurationWidth + FontWidth*1.5; \n "
" if(W0 > 6) \n "
" { \n "
" var Y0 = Y + FontHeight * 0.5; \n "
" W0 = W0 / 2.0; \n "
" var X0 = X + W0; \n "
" var X1 = X + W - W0; \n "
" context.strokeStyle = ColorFront; \n "
" context.beginPath(); \n "
" context.moveTo(X, Y0); \n "
" context.lineTo(X0, Y0); \n "
" context.moveTo(X0, Y0-2); \n "
" context.lineTo(X0, Y0+2); \n "
" context.moveTo(X1, Y0-2); \n "
" context.lineTo(X1, Y0+2); \n "
" context.moveTo(X1, Y0); \n "
" context.lineTo(X + W, Y0); \n "
" context.stroke(); \n "
" } \n "
" } \n "
" context.textAlign = \' left \' ; \n "
" DrawTextBox(context, \' \' + fEnd.toFixed(2), X + W + 2, TextPosY, \' left \' ); \n "
" DrawTextBox(context, Name, X + W + 2, nHeight - FontHeight - YSpace*Offset, \' left \' ); \n "
" Offset += 1; \n "
" } \n "
" return Offset; \n "
" } \n "
" \n "
" function DrawDetailed(Animation) \n "
" { \n "
" if(AnimationActive != Animation || !Initialized) \n "
" { \n "
" return; \n "
" } \n "
" ProfileEnter( \" DrawDetailed \" ); \n "
" DebugDrawQuadCount = 0; \n "
" DebugDrawTextCount = 0; \n "
" nHoverCSCpuNext = -1; \n "
" \n "
" fRangeBeginNext = fRangeEndNext = -1; \n "
" fRangeBeginGpuNext = fRangeEndGpuNext = -1; \n "
" var fRangeBeginGpu = -1; \n "
" var fRangeEndGpu = -1; \n "
" \n "
" var start = new Date(); \n "
" nDrawCount++; \n "
" \n "
" var context = CanvasDetailedView.getContext( \' 2d \' ); \n "
" var offscreen = CanvasDetailedOffscreen.getContext( \' 2d \' ); \n "
" var fScaleX = nWidth / fDetailedRange; \n "
" var fOffsetY = -nOffsetY + BoxHeight; \n "
" \n "
" if(DetailedRedrawState.fOffsetY == fOffsetY && DetailedRedrawState.fDetailedOffset == fDetailedOffset && DetailedRedrawState.fDetailedRange == fDetailedRange && !KeyCtrlDown && !KeyShiftDown && !MouseDragButton) \n "
" { \n "
" Invalidate++; \n "
" } \n "
" else \n "
" { \n "
" Invalidate = 0; \n "
" DetailedRedrawState.fOffsetY = fOffsetY; \n "
" DetailedRedrawState.fDetailedOffset = fDetailedOffset; \n "
" DetailedRedrawState.fDetailedRange = fDetailedRange; \n "
" } \n "
" if(Invalidate == 0) //when panning, only draw bars that are a certain width to keep decent framerate \n "
" { \n "
" context.clearRect(0, 0, CanvasDetailedView.width, CanvasDetailedView.height); \n "
" DrawDetailedView(context, nMinWidthPan, true); \n "
" } \n "
" else if(Invalidate == 1) //draw full and store \n "
" { \n "
" offscreen.clearRect(0, 0, CanvasDetailedView.width, CanvasDetailedView.height); \n "
" DrawDetailedView(offscreen, nMinWidth, true); \n "
" OffscreenData = offscreen.getImageData(0, 0, CanvasDetailedOffscreen.width, CanvasDetailedOffscreen.height); \n "
" } \n "
" else//reuse stored result untill next time viewport is changed. \n "
" { \n "
" context.clearRect(0, 0, CanvasDetailedView.width, CanvasDetailedView.height); \n "
" context.putImageData(OffscreenData, 0, 0); \n "
" DrawDetailedView(context, nMinWidth, false); \n "
" } \n "
" \n "
" if(KeyShiftDown || KeyCtrlDown || MouseDragButton || MouseDragSelectRange()) \n "
" { \n "
" nHoverToken = -1; \n "
" nHoverTokenIndex = -1; \n "
" nHoverTokenLogIndex = -1; \n "
" fRangeBegin = fRangeEnd = -1; \n "
" } \n "
" else \n "
" { \n "
" nHoverToken = nHoverTokenNext; \n "
" nHoverTokenIndex = nHoverTokenIndexNext; \n "
" nHoverTokenLogIndex = nHoverTokenLogIndexNext; \n "
" if(fRangeBeginHistory < fRangeEndHistory) \n "
" { \n "
" fRangeBegin = fRangeBeginHistory; \n "
" fRangeEnd = fRangeEndHistory; \n "
" fRangeBeginGpu = fRangeBeginHistoryGpu; \n "
" fRangeEndGpu = fRangeEndHistoryGpu; \n "
" } \n "
" else \n "
" { \n "
" fRangeBegin = fRangeBeginNext; \n "
" fRangeEnd = fRangeEndNext; \n "
" fRangeBeginGpu = fRangeBeginGpuNext; \n "
" fRangeEndGpu = fRangeEndGpuNext; \n "
" } \n "
" } \n "
" \n "
" DrawTextBox(context, TimeToMsString(fDetailedOffset), 0, FontHeight, \' left \' ); \n "
" context.textAlign = \' right \' ; \n "
" DrawTextBox(context, TimeToMsString(fDetailedOffset + fDetailedRange), nWidth, FontHeight, \' right \' ); \n "
" context.textAlign = \' left \' ; \n "
" \n "
" var Offset = 0; \n "
" Offset = DrawRange(context, fRangeBeginSelect, fRangeEndSelect, \' #59d0ff \' , \' #00ddff \' , Offset, \" Selection \" ); \n "
" Offset = DrawRange(context, fRangeBegin, fRangeEnd, \' #009900 \' , \' #00ff00 \' , Offset, \" Cpu \" ); \n "
" Offset = DrawRange(context, fRangeBeginGpu, fRangeEndGpu, \' #996600 \' , \' #775500 \' , Offset, \" Gpu \" ); \n "
" \n "
" nHoverCSCpu = nHoverCSCpuNext; \n "
" ProfileLeave(); \n "
" } \n "
" \n "
" function ZoomTo(fZoomBegin, fZoomEnd) \n "
" { \n "
" if(fZoomBegin < fZoomEnd) \n "
" { \n "
" AnimationActive = true; \n "
" var fDetailedOffsetOriginal = fDetailedOffset; \n "
" var fDetailedRangeOriginal = fDetailedRange; \n "
" var fDetailedOffsetTarget = fZoomBegin; \n "
" var fDetailedRangeTarget = fZoomEnd - fZoomBegin; \n "
" var TimestampStart = new Date(); \n "
" var count = 0; \n "
" function ZoomFunc(Timestamp) \n "
" { \n "
" var fPrc = (new Date() - TimestampStart) / (ZOOM_TIME * 1000.0); \n "
" if(fPrc > 1.0) \n "
" { \n "
" fPrc = 1.0; \n "
" } \n "
" fPrc = Math.pow(fPrc, 0.3); \n "
" fDetailedOffset = fDetailedOffsetOriginal + (fDetailedOffsetTarget - fDetailedOffsetOriginal) * fPrc; \n "
" fDetailedRange = fDetailedRangeOriginal + (fDetailedRangeTarget - fDetailedRangeOriginal) * fPrc; \n "
" DrawDetailed(true); \n "
" if(fPrc >= 1.0) \n "
" { \n "
" AnimationActive = false; \n "
" fDetailedOffset = fDetailedOffsetTarget; \n "
" fDetailedRange = fDetailedRangeTarget; \n "
" } \n "
" else \n "
" { \n "
" requestAnimationFrame(ZoomFunc); \n "
" } \n "
" } \n "
" requestAnimationFrame(ZoomFunc); \n "
" } \n "
" } \n "
" function RequestRedraw() \n "
" { \n "
" Invalidate = 0; \n "
" Draw(1); \n "
" } \n "
" function Draw(RedrawMode) \n "
" { \n "
" if(ProfileMode) \n "
" { \n "
" ProfileModeClear(); \n "
" ProfileEnter( \" Total \" ); \n "
" } \n "
" if(RedrawMode == 1) \n "
" { \n "
" if(Mode == ModeTimers) \n "
" { \n "
" DrawBarView(); \n "
" DrawHoverToolTip(); \n "
" } \n "
" else if(Mode == ModeDetailed) \n "
" { \n "
" DrawDetailed(false); \n "
" DrawHoverToolTip(); \n "
" } \n "
" } \n "
" DrawDetailedFrameHistory(); \n "
" \n "
" if(ProfileMode) \n "
" { \n "
" ProfileLeave(); \n "
" ProfileModeDraw(CanvasDetailedView); \n "
" } \n "
" } \n "
" \n "
" function AutoRedraw(Timestamp) \n "
" { \n "
" var RedrawMode = 0; \n "
" if(Mode == ModeDetailed) \n "
" { \n "
" if(ProfileMode == 2 || ((nHoverCSCpu >= 0 || nHoverToken != -1) && !KeyCtrlDown && !KeyShiftDown && !MouseDragButton)||(Invalidate<2 && !KeyCtrlDown && !KeyShiftDown && !MouseDragButton)) \n "
" { \n "
" RedrawMode = 1; \n "
" } \n "
" } \n "
" else \n "
" { \n "
" if(Invalidate < 1) \n "
" { \n "
" RedrawMode = 1; \n "
" } \n "
" } \n "
" if(RedrawMode) \n "
" { \n "
" Draw(RedrawMode); \n "
" } \n "
" else if(FlashFrameCounter>0) \n "
" { \n "
" Draw(0); \n "
" } \n "
" requestAnimationFrame(AutoRedraw); \n "
" } \n "
" \n "
" \n "
" function ZoomGraph(nZoom) \n "
" { \n "
" var fOldRange = fDetailedRange; \n "
" if(nZoom>0) \n "
" { \n "
" fDetailedRange *= Math.pow(nModDown ? 1.40 : 1.03, nZoom); \n "
" } \n "
" else \n "
" { \n "
" var fNewDetailedRange = fDetailedRange / Math.pow((nModDown ? 1.40 : 1.03), -nZoom); \n "
" if(fNewDetailedRange < 0.0001) //100ns \n "
" fNewDetailedRange = 0.0001; \n "
" fDetailedRange = fNewDetailedRange; \n "
" } \n "
" \n "
" var fDiff = fOldRange - fDetailedRange; \n "
" var fMousePrc = DetailedViewMouseX / nWidth; \n "
" if(fMousePrc < 0) \n "
" { \n "
" fMousePrc = 0; \n "
" } \n "
" fDetailedOffset += fDiff * fMousePrc; \n "
" \n "
" } \n "
" \n "
" function MeasureFont() \n "
" { \n "
" var context = CanvasDetailedView.getContext( \' 2d \' ); \n "
" context.font = Font; \n "
" FontWidth = context.measureText( \' W \' ).width; \n "
" \n "
" } \n "
" function ResizeCanvas() \n "
" { \n "
" nWidth = window.innerWidth; \n "
" nHeight = window.innerHeight - CanvasHistory.height-2; \n "
" DPR = window.devicePixelRatio; \n "
" \n "
" if(DPR) \n "
" { \n "
" CanvasDetailedView.style.width = nWidth + \' px \' ; \n "
" CanvasDetailedView.style.height = nHeight + \' px \' ; \n "
" CanvasDetailedView.width = nWidth * DPR; \n "
" CanvasDetailedView.height = nHeight * DPR; \n "
" CanvasHistory.style.width = window.innerWidth + \' px \' ; \n "
" CanvasHistory.style.height = 70 + \' px \' ; \n "
" CanvasHistory.width = window.innerWidth * DPR; \n "
" CanvasHistory.height = 70 * DPR; \n "
" CanvasHistory.getContext( \' 2d \' ).scale(DPR,DPR); \n "
" CanvasDetailedView.getContext( \' 2d \' ).scale(DPR,DPR); \n "
" \n "
" CanvasDetailedOffscreen.style.width = nWidth + \' px \' ; \n "
" CanvasDetailedOffscreen.style.height = nHeight + \' px \' ; \n "
" CanvasDetailedOffscreen.wid " ;
const size_t g_MicroProfileHtml_end_1_size = sizeof ( g_MicroProfileHtml_end_1 ) ;
const char g_MicroProfileHtml_end_2 [ ] =
" th = nWidth * DPR; \n "
" CanvasDetailedOffscreen.height = nHeight * DPR; \n "
" CanvasDetailedOffscreen.getContext( \' 2d \' ).scale(DPR,DPR); \n "
" \n "
" } \n "
" else \n "
" { \n "
" DPR = 1; \n "
" CanvasDetailedView.width = nWidth; \n "
" CanvasDetailedView.height = nHeight; \n "
" CanvasDetailedOffscreen.width = nWidth; \n "
" CanvasDetailedOffscreen.height = nHeight; \n "
" CanvasHistory.width = window.innerWidth; \n "
" } \n "
" RequestRedraw(); \n "
" } \n "
" \n "
" var MouseDragOff = 0; \n "
" var MouseDragDown = 1; \n "
" var MouseDragUp = 2; \n "
" var MouseDragMove = 3; \n "
" var MouseDragState = MouseDragOff; \n "
" var MouseDragTarget = 0; \n "
" var MouseDragButton = 0; \n "
" var MouseDragKeyShift = 0; \n "
" var MouseDragKeyCtrl = 0; \n "
" var MouseDragX = 0; \n "
" var MouseDragY = 0; \n "
" var MouseDragXLast = 0; \n "
" var MouseDragYLast = 0; \n "
" var MouseDragXStart = 0; \n "
" var MouseDragYStart = 0; \n "
" \n "
" function clamp(number, min, max) \n "
" { \n "
" return Math.max(min, Math.min(number, max)); \n "
" } \n "
" \n "
" function MouseDragPan() \n "
" { \n "
" return MouseDragButton == 1 || MouseDragKeyShift; \n "
" } \n "
" function MouseDragSelectRange() \n "
" { \n "
" return MouseDragState == MouseDragMove && (MouseDragButton == 3 || (MouseDragKeyShift && MouseDragKeyCtrl)); \n "
" } \n "
" function MouseHandleDrag() \n "
" { \n "
" if(MouseDragTarget == CanvasDetailedView) \n "
" { \n "
" if(Mode == ModeDetailed) \n "
" { \n "
" if(MouseDragSelectRange()) \n "
" { \n "
" var xStart = MouseDragXStart; \n "
" var xEnd = MouseDragX; \n "
" if(xStart > xEnd) \n "
" { \n "
" var Temp = xStart; \n "
" xStart = xEnd; \n "
" xEnd = Temp; \n "
" } \n "
" if(xEnd - xStart > 1) \n "
" { \n "
" fRangeBegin = fDetailedOffset + fDetailedRange * (xStart / nWidth); \n "
" fRangeEnd = fDetailedOffset + fDetailedRange * (xEnd / nWidth); \n "
" fRangeBeginSelect = fDetailedOffset + fDetailedRange * (xStart / nWidth); \n "
" fRangeEndSelect = fDetailedOffset + fDetailedRange * (xEnd / nWidth); \n "
" } \n "
" } \n "
" else if(MouseDragPan()) \n "
" { \n "
" var X = MouseDragX - MouseDragXLast; \n "
" var Y = MouseDragY - MouseDragYLast; \n "
" if(X) \n "
" { \n "
" fDetailedOffset += -X * fDetailedRange / nWidth; \n "
" } \n "
" nOffsetY -= Y; \n "
" if(nOffsetY < 0) \n "
" { \n "
" nOffsetY = 0; \n "
" } \n "
" } \n "
" else if(MouseDragKeyCtrl) \n "
" { \n "
" if(MouseDragY != MouseDragYLast) \n "
" { \n "
" ZoomGraph(MouseDragY - MouseDragYLast); \n "
" } \n "
" } \n "
" } \n "
" else if(Mode == ModeTimers) \n "
" { \n "
" if(MouseDragKeyShift || MouseDragButton == 1) \n "
" { \n "
" var X = MouseDragX - MouseDragXLast; \n "
" var Y = MouseDragY - MouseDragYLast; \n "
" nOffsetBarsY -= Y; \n "
" nOffsetBarsX -= X; \n "
" if(nOffsetBarsY < 0) \n "
" { \n "
" nOffsetBarsY = 0; \n "
" } \n "
" if(nOffsetBarsX < 0) \n "
" { \n "
" nOffsetBarsX = 0; \n "
" } \n "
" } \n "
" \n "
" } \n "
" \n "
" } \n "
" else if(MouseDragTarget == CanvasHistory) \n "
" { \n "
" function HistoryFrameTime(x) \n "
" { \n "
" var NumFrames = Frames.length; \n "
" var fBarWidth = nWidth / NumFrames; \n "
" var Index = clamp(Math.floor(NumFrames * x / nWidth), 0, NumFrames-1); \n "
" var Lerp = clamp((x/fBarWidth - Index) , 0, 1); \n "
" var time = Frames[Index].framestart + (Frames[Index].frameend - Frames[Index].framestart) * Lerp; \n "
" return time; \n "
" } \n "
" if(MouseDragSelectRange()) \n "
" { \n "
" fRangeBegin = fRangeEnd = -1; \n "
" \n "
" var xStart = MouseDragXStart; \n "
" var xEnd = MouseDragX; \n "
" if(xStart > xEnd) \n "
" { \n "
" var Temp = xStart; \n "
" xStart = xEnd; \n "
" xEnd = Temp; \n "
" } \n "
" if(xEnd - xStart > 2) \n "
" { \n "
" var timestart = HistoryFrameTime(xStart); \n "
" var timeend = HistoryFrameTime(xEnd); \n "
" fDetailedOffset = timestart; \n "
" fDetailedRange = timeend-timestart; \n "
" } \n "
" } \n "
" else if(MouseDragPan()) \n "
" { \n "
" var Time = HistoryFrameTime(MouseDragX); \n "
" fDetailedOffset = Time - fDetailedRange / 2.0; \n "
" } \n "
" } \n "
" } \n "
" function MouseHandleDragEnd() \n "
" { \n "
" if(MouseDragTarget == CanvasDetailedView) \n "
" { \n "
" \n "
" } \n "
" else if(MouseDragTarget == CanvasHistory) \n "
" { \n "
" if(!MouseDragSelectRange() && !MouseDragPan()) \n "
" { \n "
" ZoomTo(fRangeBegin, fRangeEnd); \n "
" fRangeBegin = fRangeEnd = -1; \n "
" } \n "
" \n "
" \n "
" } \n "
" \n "
" } \n "
" \n "
" function MouseHandleDragClick() \n "
" { \n "
" if(MouseDragTarget == CanvasDetailedView) \n "
" { \n "
" ZoomTo(fRangeBegin, fRangeEnd); \n "
" } \n "
" else if(MouseDragTarget == CanvasHistory) \n "
" { \n "
" if(Mode == ModeDetailed) \n "
" { \n "
" ZoomTo(fRangeBegin, fRangeEnd); \n "
" } \n "
" } \n "
" } \n "
" \n "
" function MapMouseButton(Event) \n "
" { \n "
" if(event.button == 1 || event.which == 1) \n "
" { \n "
" return 1; \n "
" } \n "
" else if(event.button == 3 || event.which == 3) \n "
" { \n "
" return 3; \n "
" } \n "
" else \n "
" { \n "
" return 0; \n "
" } \n "
" } \n "
" \n "
" function MouseDragReset() \n "
" { \n "
" MouseDragState = MouseDragOff; \n "
" MouseDragTarget = 0; \n "
" MouseDragKeyShift = 0; \n "
" MouseDragKeyCtrl = 0; \n "
" MouseDragButton = 0; \n "
" } \n "
" function MouseDragKeyUp() \n "
" { \n "
" if((MouseDragKeyShift && !KeyShiftDown) || (MouseDragKeyCtrl && !KeyCtrlDown)) \n "
" { \n "
" MouseHandleDragEnd(); \n "
" MouseDragReset(); \n "
" } \n "
" } \n "
" function MouseDrag(Source, Event) \n "
" { \n "
" if(Source == MouseDragOff || (MouseDragTarget && MouseDragTarget != Event.target)) \n "
" { \n "
" MouseDragReset(); \n "
" return; \n "
" } \n "
" \n "
" var LocalRect = Event.target.getBoundingClientRect(); \n "
" MouseDragX = Event.clientX - LocalRect.left; \n "
" MouseDragY = Event.clientY - LocalRect.top; \n "
" // console.log( \' cur drag state \' + MouseDragState + \' Source \' + Source); \n "
" if(MouseDragState == MouseDragMove) \n "
" { \n "
" var dx = Math.abs(MouseDragX - MouseDragXStart); \n "
" var dy = Math.abs(MouseDragY - MouseDragYStart); \n "
" if((Source == MouseDragUp && MapMouseButton(Event) == MouseDragButton) || \n "
" (MouseDragKeyCtrl && !KeyCtrlDown) || \n "
" (MouseDragKeyShift && !KeyShiftDown)) \n "
" { \n "
" MouseHandleDragEnd(); \n "
" MouseDragReset(); \n "
" return; \n "
" } \n "
" else \n "
" { \n "
" MouseHandleDrag(); \n "
" } \n "
" } \n "
" else if(MouseDragState == MouseDragOff) \n "
" { \n "
" if(Source == MouseDragDown || KeyShiftDown || KeyCtrlDown) \n "
" { \n "
" MouseDragTarget = Event.target; \n "
" MouseDragButton = MapMouseButton(Event); \n "
" MouseDragState = MouseDragDown; \n "
" MouseDragXStart = MouseDragX; \n "
" MouseDragYStart = MouseDragY; \n "
" MouseDragKeyCtrl = 0; \n "
" MouseDragKeyShift = 0; \n "
" \n "
" if(KeyShiftDown || KeyCtrlDown) \n "
" { \n "
" MouseDragKeyShift = KeyShiftDown; \n "
" MouseDragKeyCtrl = KeyCtrlDown; \n "
" MouseDragState = MouseDragMove; \n "
" } \n "
" } \n "
" } \n "
" else if(MouseDragState == MouseDragDown) \n "
" { \n "
" if(Source == MouseDragUp) \n "
" { \n "
" MouseHandleDragClick(); \n "
" MouseDragReset(); \n "
" } \n "
" else if(Source == MouseDragMove) \n "
" { \n "
" var dx = Math.abs(MouseDragX - MouseDragXStart); \n "
" var dy = Math.abs(MouseDragY - MouseDragYStart); \n "
" if(dx+dy>1) \n "
" { \n "
" MouseDragState = MouseDragMove; \n "
" } \n "
" } \n "
" } \n "
" MouseDragXLast = MouseDragX; \n "
" MouseDragYLast = MouseDragY; \n "
" } \n "
" \n "
" function MouseMove(evt) \n "
" { \n "
" evt.preventDefault(); \n "
" MouseDrag(MouseDragMove, evt); \n "
" MouseHistory = 0; \n "
" MouseDetailed = 0; \n "
" HistoryViewMouseX = HistoryViewMouseY = -1; \n "
" var rect = evt.target.getBoundingClientRect(); \n "
" var x = evt.clientX - rect.left; \n "
" var y = evt.clientY - rect.top; \n "
" if(evt.target == CanvasDetailedView) \n "
" { \n "
" if(!MouseDragSelectRange()) \n "
" { \n "
" fRangeBegin = fRangeEnd = -1; \n "
" } \n "
" DetailedViewMouseX = x; \n "
" DetailedViewMouseY = y; \n "
" } \n "
" else if(evt.target = CanvasHistory) \n "
" { \n "
" var Rect = CanvasHistory.getBoundingClientRect(); \n "
" HistoryViewMouseX = x; \n "
" HistoryViewMouseY = y; \n "
" } \n "
" Draw(1); \n "
" } \n "
" \n "
" function MouseButton(bPressed, evt) \n "
" { \n "
" evt.preventDefault(); \n "
" MouseDrag(bPressed ? MouseDragDown : MouseDragUp, evt); \n "
" } \n "
" \n "
" function MouseOut(evt) \n "
" { \n "
" MouseDrag(MouseDragOff, evt); \n "
" KeyCtrlDown = 0; \n "
" KeyShiftDown = 0; \n "
" MouseDragButton = 0; \n "
" nHoverToken = -1; \n "
" fRangeBegin = fRangeEnd = -1; \n "
" } \n "
" \n "
" function MouseWheel(e) \n "
" { \n "
" var e = window.event || e; \n "
" var delta = (e.wheelDelta || e.detail * (-120)); \n "
" ZoomGraph((-4 * delta / 120.0) | 0); \n "
" Draw(1); \n "
" } \n "
" \n "
" \n "
" function KeyUp(evt) \n "
" { \n "
" if(evt.keyCode == 17) \n "
" { \n "
" KeyCtrlDown = 0; \n "
" MouseDragKeyUp(); \n "
" } \n "
" else if(evt.keyCode == 16) \n "
" { \n "
" KeyShiftDown = 0; \n "
" MouseDragKeyUp(); \n "
" } \n "
" if(evt.keyCode == 18) \n "
" { \n "
" FlipToolTip = 0; \n "
" } \n "
" if(evt.keyCode == 32) \n "
" { \n "
" if(fRangeBeginSelect < fRangeEndSelect) \n "
" { \n "
" ZoomTo(fRangeBeginSelect, fRangeEndSelect); \n "
" fRangeBeginSelect = fRangeEndSelect = -1; \n "
" MouseHandleDragEnd(); \n "
" } \n "
" } \n "
" if(evt.keyCode == 27) \n "
" { \n "
" fRangeBeginSelect = fRangeEndSelect = -1; \n "
" } \n "
" Invalidate = 0; \n "
" } \n "
" \n "
" function KeyDown(evt) \n "
" { \n "
" if(evt.keyCode == 18) \n "
" { \n "
" FlipToolTip = 1; \n "
" } \n "
" if(evt.keyCode == 17) \n "
" { \n "
" KeyCtrlDown = 1; \n "
" } \n "
" else if(evt.keyCode == 16) \n "
" { \n "
" KeyShiftDown = 1; \n "
" } \n "
" Invalidate = 0; \n "
" } \n "
" \n "
" function ReadCookie() \n "
" { \n "
" var result = document.cookie.match(/fisk=([^;]+)/); \n "
" var NewMode = ModeDetailed; \n "
" var ReferenceTimeString = \' 33ms \' ; \n "
" if(result && result.length > 0) \n "
" { \n "
" var Obj = JSON.parse(result[1]); \n "
" if(Obj.Mode) \n "
" { \n "
" NewMode = Obj.Mode; \n "
" } \n "
" if(Obj.ReferenceTime) \n "
" { \n "
" ReferenceTimeString = Obj.ReferenceTime; \n "
" } \n "
" if(Obj.ThreadsAllActive || Obj.ThreadsAllActive == 0 || Obj.ThreadsAllActive == false) \n "
" { \n "
" ThreadsAllActive = Obj.ThreadsAllActive; \n "
" } \n "
" else \n "
" { \n "
" ThreadsAllActive = 1; \n "
" } \n "
" if(Obj.ThreadsActive) \n "
" { \n "
" ThreadsActive = Obj.ThreadsActive; \n "
" } \n "
" if(Obj.GroupsAllActive || Obj.GroupsAllActive == 0 || Obj.GroupsAllActive) \n "
" { \n "
" GroupsAllActive = Obj.GroupsAllActive; \n "
" } \n "
" else \n "
" { \n "
" GroupsAllActive = 1; \n "
" } \n "
" if(Obj.GroupsActive) \n "
" { \n "
" GroupsActive = Obj.GroupsActive; \n "
" } \n "
" if(Obj.nContextSwitchEnabled) \n "
" { \n "
" nContextSwitchEnabled = Obj.nContextSwitchEnabled; \n "
" } \n "
" else \n "
" { \n "
" nContextSwitchEnabled = 1; \n "
" } \n "
" if(Obj.GroupColors) \n "
" { \n "
" GroupColors = Obj.GroupColors; \n "
" } \n "
" else \n "
" { \n "
" GroupColors = 0; \n "
" } \n "
" if(Obj.nHideHelp) \n "
" { \n "
" nHideHelp = 1; \n "
" } \n "
" TimersGroups = Obj.TimersGroups?Obj.TimersGroups:0; \n "
" TimersMeta = Obj.TimersMeta?0:1; \n "
" } \n "
" SetContextSwitch(nContextSwitchEnabled); \n "
" SetMode(NewMode, TimersGroups); \n "
" SetReferenceTime(ReferenceTimeString); \n "
" UpdateOptionsMenu(); \n "
" UpdateGroupColors(); \n "
" } \n "
" function WriteCookie() \n "
" { \n "
" var Obj = new Object(); \n "
" Obj.Mode = Mode; \n "
" Obj.ReferenceTime = ReferenceTime + \' ms \' ; \n "
" Obj.ThreadsActive = ThreadsActive; \n "
" Obj.ThreadsAllActive = ThreadsAllActive; \n "
" Obj.GroupsActive = GroupsActive; \n "
" Obj.GroupsAllActive = GroupsAllActive; \n "
" Obj.nContextSwitchEnabled = nContextSwitchEnabled; \n "
" Obj.TimersGroups = TimersGroups?TimersGroups:0; \n "
" Obj.TimersMeta = TimersMeta?0:1; \n "
" Obj.GroupColors = GroupColors; \n "
" if(nHideHelp) \n "
" { \n "
" Obj.nHideHelp = 1; \n "
" } \n "
" var date = new Date(); \n "
" date.setFullYear(2099); \n "
" var cookie = \' fisk= \' + JSON.stringify(Obj) + \' ;expires= \' + date; \n "
" document.cookie = cookie; \n "
" } \n "
" \n "
" var mousewheelevt = (/Firefox/i.test(navigator.userAgent)) ? \" DOMMouseScroll \" : \" mousewheel \" //FF doesn \' t recognize mousewheel as of FF3.x \n "
" \n "
" CanvasDetailedView.addEventListener( \' mousemove \' , MouseMove, false); \n "
" CanvasDetailedView.addEventListener( \' mousedown \' , function(evt) { MouseButton(true, evt); }); \n "
" CanvasDetailedView.addEventListener( \' mouseup \' , function(evt) { MouseButton(false, evt); } ); \n "
" CanvasDetailedView.addEventListener( \' mouseout \' , MouseOut); \n "
" CanvasDetailedView.addEventListener( \" contextmenu \" , function (e) { e.preventDefault(); }, false); \n "
" CanvasDetailedView.addEventListener(mousewheelevt, MouseWheel, false); \n "
" CanvasHistory.addEventListener( \' mousemove \' , MouseMove); \n "
" CanvasHistory.addEventListener( \' mousedown \' , function(evt) { MouseButton(true, evt); }); \n "
" CanvasHistory.addEventListener( \' mouseup \' , function(evt) { MouseButton(false, evt); } ); \n "
" CanvasHistory.addEventListener( \' mouseout \' , MouseOut); \n "
" CanvasHistory.addEventListener( \" contextmenu \" , function (e) { e.preventDefault(); }, false); \n "
" CanvasHistory.addEventListener(mousewheelevt, MouseWheel, false); \n "
" window.addEventListener( \' keydown \' , KeyDown); \n "
" window.addEventListener( \' keyup \' , KeyUp); \n "
" window.addEventListener( \' resize \' , ResizeCanvas, false); \n "
" \n "
" function CalcAverage() \n "
" { \n "
" var Sum = 0; \n "
" var Count = 0; \n "
" for(nLog = 0; nLog < nNumLogs; nLog++) \n "
" { \n "
" StackPos = 0; \n "
" for(var i = 0; i < Frames.length; i++) \n "
" { \n "
" var Frame_ = Frames[i]; \n "
" var tt = Frame_.tt[nLog]; \n "
" var ts = Frame_.ts[nLog]; \n "
" \n "
" var count = tt.length; \n "
" for(var j = 0; j < count; j++) \n "
" { \n "
" var type = tt[j]; \n "
" var time = ts[j]; \n "
" if(type == 1) \n "
" { \n "
" Stack[StackPos] = time;//store the frame which it comes from \n "
" StackPos++; \n "
" } \n "
" else if(type == 0) \n "
" { \n "
" if(StackPos>0) \n "
" { \n "
" \n "
" StackPos--; \n "
" var localtime = time - Stack[StackPos]; \n "
" Count++; \n "
" Sum += localtime; \n "
" } \n "
" } \n "
" } \n "
" } \n "
" } \n "
" return Sum / Count; \n "
" \n "
" } \n "
" \n "
" function MakeLod(index, MinDelta, TimeArray, TypeArray, IndexArray, LogStart) \n "
" { \n "
" if(LodData[index]) \n "
" { \n "
" console.log( \" error!! \" ); \n "
" } \n "
" // debugger; \n "
" var o = new Object(); \n "
" o.MinDelta = MinDelta; \n "
" o.TimeArray = TimeArray; \n "
" o.TypeArray = TypeArray; \n "
" o.IndexArray = IndexArray; \n "
" o.LogStart = LogStart; \n "
" LodData[index] = o; \n "
" } \n "
" \n "
" function PreprocessBuildSplitArray() \n "
" { \n "
" var nNumLogs = Frames[0].ts.length; \n "
" \n "
" ProfileEnter( \" PreprocessBuildSplitArray \" ); \n "
" var SplitArrays = new Array(nNumLogs); \n "
" \n "
" for(nLog = 0; nLog < nNumLogs; ++nLog) \n "
" { \n "
" console.log( \" source log \" + nLog + \" size \" + LodData[0].TypeArray[nLog].length); \n "
" } \n "
" \n "
" \n "
" for(nLog = 0; nLog < nNumLogs; nLog++) \n "
" { \n "
" var MaxDepth = 1; \n "
" var StackPos = 0; \n "
" var Stack = Array(20); \n "
" var TypeArray = LodData[0].TypeArray[nLog]; \n "
" var TimeArray = LodData[0].TimeArray[nLog]; \n "
" var DeltaTimes = new Array(TypeArray.length); \n "
" \n "
" for(var j = 0; j < TypeArray.length; ++j) \n "
" { \n "
" var type = TypeArray[j]; \n "
" var time = TimeArray[j]; \n "
" if(type == 1) \n "
" { \n "
" //push \n "
" Stack[StackPos] = time; \n "
" StackPos++; \n "
" } \n "
" else if(type == 0) \n "
" { \n "
" if(StackPos>0) \n "
" { \n "
" StackPos--; \n "
" DeltaTimes[j] = time - Stack[StackPos]; \n "
" } \n "
" else \n "
" { \n "
" DeltaTimes[j] = 0; \n "
" } \n "
" } \n "
" } \n "
" DeltaTimes.sort(function(a,b){return b-a;}); \n "
" var SplitArray = Array(NumLodSplits); \n "
" var SplitIndex = DeltaTimes.length; \n "
" \n "
" var j = 0; \n "
" for(j = 0; j < NumLodSplits; ++j) \n "
" { \n "
" SplitIndex = Math.floor(SplitIndex / 2); \n "
" while(SplitIndex > 0 && !DeltaTimes[SplitIndex]) \n "
" { \n "
" SplitIndex--; \n "
" } \n "
" if(SplitIndex < SplitMin) \n "
" { \n "
" break; \n "
" } \n "
" //search.. if 0 \n "
" var SplitTime = DeltaTimes[SplitIndex]; \n "
" if(SplitTime>=0) \n "
" { \n "
" SplitArray[j] = SplitTime; \n "
" } \n "
" else \n "
" { \n "
" SplitArray[j] = SPLIT_LIMIT; \n "
" } \n "
" if(j>0) \n "
" { \n "
" console.assert(SplitArray[j-1] <= SplitArray[j], \" must be less \" ); \n "
" } \n "
" \n "
" } \n "
" for(; j < NumLodSplits; ++j) \n "
" { \n "
" SplitArray[j] = SPLIT_LIMIT; \n "
" // console.log( \" split skipping \" + j + \" \" + SPLIT_LIMIT); \n "
" } \n "
" \n "
" \n "
" SplitArrays[nLog] = SplitArray; \n "
" } \n "
" ProfileLeave(); \n "
" return SplitArrays; \n "
" } \n "
" \n "
" function PreprocessBuildDurationArray() \n "
" { \n "
" var nNumLogs = Frames[0].ts.length; \n "
" ProfileEnter( \" PreprocessBuildDurationArray \" ); \n "
" var DurationArrays = new Array(nNumLogs); \n "
" for(nLog = 0; nLog < nNumLogs; ++nLog) \n "
" { \n "
" var MaxDepth = 1; \n "
" var StackPos = 0; \n "
" var Stack = Array(20); \n "
" var StackIndex = Array(20); \n "
" var TypeArray = LodData[0].TypeArray[nLog]; \n "
" var TimeArray = LodData[0].TimeArray[nLog]; \n "
" var DurationArray = Array(LodData[0].TypeArray[nLog].length); \n "
" for(var j = 0; j < TypeArray.length; ++j) \n "
" { \n "
" var type = TypeArray[j]; \n "
" var time = TimeArray[j]; \n "
" if(type == 1) \n "
" { \n "
" //push \n "
" Stack[StackPos] = time; \n "
" StackIndex[StackPos] = j; \n "
" StackPos++; \n "
" } \n "
" else if(type == 0) \n "
" { \n "
" if(StackPos>0) \n "
" { \n "
" StackPos--; \n "
" var Duration = time - Stack[StackPos]; \n "
" DurationArray[StackIndex[StackPos]] = Duration; \n "
" DurationArray[j] = Duration; \n "
" } \n "
" else \n "
" { \n "
" DurationArray[j] = 0; \n "
" } \n "
" } \n "
" } \n "
" for(var j = 0; j < StackPos; ++j) \n "
" { \n "
" DurationArray[j] = 0; \n "
" } \n "
" DurationArrays[nLog] = DurationArray; \n "
" } \n "
" ProfileLeave(); \n "
" return DurationArrays; \n "
" \n "
" } \n "
" function PreprocessLods() \n "
" { \n "
" ProfileEnter( \" PreprocessLods \" ); \n "
" var nNumLogs = Frames[0].ts.length; \n "
" var SplitArrays = PreprocessBuildSplitArray(); \n "
" var DurationArrays = PreprocessBuildDurationArray(); \n "
" var Source = LodData[0]; \n "
" var SourceLogStart = Source.LogStart; \n "
" var NumFrames = SourceLogStart.length; \n "
" \n "
" for(var i = 0; i < NumLodSplits-1; ++i) \n "
" { \n "
" var DestLogStart = Array(SourceLogStart.length); \n "
" for(var j = 0; j < DestLogStart.length; ++j) \n "
" { \n "
" DestLogStart[j] = Array(nNumLogs); \n "
" } \n "
" var MinDelta = Array(nNumLogs); \n "
" var TimeArray = Array(nNumLogs); \n "
" var IndexArray = Array(nNumLogs); \n "
" var TypeArray = Array(nNumLogs); \n "
" \n "
" \n "
" \n "
" for(nLog = 0; nLog < nNumLogs; ++nLog) \n "
" { \n "
" var SourceTypeArray = Source.TypeArray[nLog]; \n "
" var SourceTimeArray = Source.TimeArray[nLog]; \n "
" var SourceIndexArray = Source.IndexArray[nLog]; \n "
" var Duration = DurationArrays[nLog]; \n "
" console.assert(Duration.length == SourceTypeArray.length, \" must be equal! \" ); \n "
" var SplitTime = SplitArrays[nLog][i]; \n "
" \n "
" MinDelta[nLog] = SplitTime; \n "
" if(SplitTime < SPLIT_LIMIT) \n "
" { \n "
" var SourceCount = SourceTypeArray.length; \n "
" var DestTypeArray = Array(); \n "
" var DestTimeArray = Array(); \n "
" var DestIndexArray = Array(); \n "
" var RemapArray = Array(SourceCount); \n "
" var DiscardLast = 0; \n "
" \n "
" for(var j = 0; j < SourceCount; ++j) \n "
" { \n "
" RemapArray[j] = DestTypeArray.length; \n "
" if(Duration[j] >= SplitTime || (SourceTypeArray[j] == 3 && 0 == DiscardLast)) \n "
" { \n "
" DiscardLast = 0; \n "
" DestTypeArray.push(SourceTypeArray[j]); \n "
" DestTimeArray.push(SourceTimeArray[j]); \n "
" DestIndexArray.push(SourceIndexArray[j]); \n "
" } \n "
" else \n "
" { \n "
" DiscardLast = 1; \n "
" } \n "
" } \n "
" TimeArray[nLog] = DestTimeArray; \n "
" IndexArray[nLog] = DestIndexArray; \n "
" TypeArray[nLog] = DestTypeArray; \n "
" for(var j = 0; j < NumFrames; ++j) \n "
" { \n "
" var OldStart = SourceLogStart[j][nLog]; \n "
" var NewStart = RemapArray[OldStart]; \n "
" var FrameArray = DestLogStart[j]; \n "
" FrameArray[nLog] = NewStart; \n "
" } \n "
" } \n "
" else \n "
" { \n "
" \n "
" for(var j = 0; j < NumFrames; ++j) \n "
" { \n "
" var FrameArray = DestLogStart[j]; \n "
" \n "
" FrameArray[nLog] = 0; \n "
" } \n "
" \n "
" } \n "
" \n "
" } \n "
" MakeLod(i+1, MinDelta, TimeArray, TypeArray, IndexArray, DestLogStart); \n "
" } \n "
" ProfileLeave(); \n "
" } \n "
" function PreprocessGlobalArray() \n "
" { \n "
" ProfileEnter( \" PreprocessGlobalArray \" ); \n "
" var nNumLogs = Frames[0].ts.length; \n "
" var CaptureStart = Frames[0].framestart; \n "
" var CaptureEnd = Frames[Frames.length-1].frameend; \n "
" g_TypeArray = new Array(nNumLogs); \n "
" g_TimeArray = new Array(nNumLogs); \n "
" g_IndexArray = new Array(nNumLogs); \n "
" var StackPos = 0; \n "
" var Stack = Array(20); \n "
" var LogStartArray = new Array(Frames.length); \n "
" for(var i = 0; i < Frames.length; i++) \n "
" { \n "
" Frames[i].LogStart = new Array(nNumLogs); \n "
" LogStartArray[i] = Frames[i].LogStart; \n "
" \n "
" Frames[i].LogEnd = new Array(nNumLogs); \n "
" } \n "
" var MinDelta = Array(nNumLogs); \n "
" for(nLog = 0; nLog < nNumLogs; nLog++) \n "
" { \n "
" MinDelta[nLog] = 0; \n "
" var Discard = 0; \n "
" var TypeArray = new Array(); \n "
" var TimeArray = new Array(); \n "
" var IndexArray = new Array(); \n "
" for(var i = 0; i < Frames.length; i++) \n "
" { \n "
" var Frame_ = Frames[i]; \n "
" Frame_.LogStart[nLog] = TimeArray.length; \n "
" var FrameDiscard = Frame_.frameend + 33;//if timestamps are more than 33ms after current frame, we assume buffer has wrapped. \n "
" var tt = Frame_.tt[nLog]; \n "
" var ts = Frame_.ts[nLog]; \n "
" var ti = Frame_.ti[nLog]; \n "
" var len = tt.length; \n "
" var DiscardLast = 0; \n "
" for(var xx = 0; xx < len; ++xx) \n "
" { \n "
" var Skip = (tt[i] == 3) ? DiscardLast : ts[xx] > FrameDiscard; \n "
" if(Skip) \n "
" { \n "
" Discard++; \n "
" DiscardLast = 1; \n "
" } \n "
" else \n "
" { \n "
" DiscardLast = 0; \n "
" TypeArray.push(tt[xx]); \n "
" TimeArray.push(ts[xx]); \n "
" IndexArray.push(ti[xx]); \n "
" } \n "
" } \n "
" Frame_.LogEnd[nLog] = TimeArray.length; \n "
" } \n "
" g_TypeArray[nLog] = TypeArray; \n "
" g_TimeArray[nLog] = TimeArray; \n "
" g_IndexArray[nLog] = IndexArray; \n "
" if(Discard) \n "
" { \n "
" console.log( \' discarded \' + Discard + \' markers from \' + ThreadNames[nLog]); \n "
" } \n "
" } \n "
" MakeLod(0, MinDelta, g_TimeArray, g_TypeArray, g_IndexArray, LogStartArray); \n "
" ProfileLeave(); \n "
" } \n "
" \n "
" function PreprocessFindFirstFrames() \n "
" { \n "
" ProfileEnter( \" PreprocesFindFirstFrames \" ); \n "
" //create arrays that show how far back we need to start search in order to get all markers. \n "
" var nNumLogs = Frames[0].ts.length; \n "
" for(var i = 0; i < Frames.length; i++) \n "
" { \n "
" Frames[i].FirstFrameIndex = new Array(nNumLogs); \n "
" } \n "
" \n "
" var StackPos = 0; \n "
" var Stack = Array(20); \n "
" g_MaxStack = Array(nNumLogs); \n "
" \n "
" for(nLog = 0; nLog < nNumLogs; nLog++) \n "
" { \n "
" var MaxStack = 0; \n "
" StackPos = 0; \n "
" for(var i = 0; i < Frames.length; i++) \n "
" { \n "
" var Frame_ = Frames[i]; \n "
" var tt = Frame_.tt[nLog]; \n "
" var count = tt.length; \n "
" \n "
" var FirstFrame = i; \n "
" if(StackPos>0) \n "
" { \n "
" FirstFrame = Stack[0]; \n "
" } \n "
" Frames[i].FirstFrameIndex[nLog] = FirstFrame; \n "
" \n "
" for(var j = 0; j < count; j++) \n "
" { \n "
" var type = tt[j]; \n "
" if(type == 1) \n "
" { \n "
" Stack[StackPos] = i;//store the frame which it comes from \n "
" StackPos++; \n "
" if(StackPos > MaxStack) \n "
" { \n "
" MaxStack = StackPos; \n "
" } \n "
" } \n "
" else if(type == 0) \n "
" { \n "
" if(StackPos>0) \n "
" { \n "
" StackPos--; \n "
" } \n "
" } \n "
" } \n "
" } \n "
" g_MaxStack[nLog] = MaxStack; \n "
" } \n "
" ProfileLeave(); \n "
" } \n "
" function PreprocessMeta() \n "
" { \n "
" MetaLengths = Array(MetaNames.length); \n "
" MetaLengthsAvg = Array(MetaNames.length); \n "
" MetaLengthsMax = Array(MetaNames.length); \n "
" for(var i = 0; i < MetaNames.length; ++i) \n "
" { \n "
" MetaLengths[i] = MetaNames[i].length+1; \n "
" MetaLengthsAvg[i] = MetaNames[i].length+5; \n "
" MetaLengthsMax[i] = MetaNames[i].length+5; \n "
" if(MetaLengths[i]<12) \n "
" MetaLengths[i] = 12; \n "
" if(MetaLengthsAvg[i]<12) \n "
" MetaLengthsAvg[i] = 12; \n "
" if(MetaLengthsMax[i]<12) \n "
" MetaLengthsMax[i] = 12; \n "
" } \n "
" for(var i = 0; i < TimerInfo.length; ++i) \n "
" { \n "
" var Timer = TimerInfo[i]; \n "
" for(var j = 0; j < MetaNames.length; ++j) \n "
" { \n "
" var Len = FormatMeta(Timer.meta[j],0).length + 2; \n "
" var LenAvg = FormatMeta(Timer.meta[j],2).length + 2; \n "
" var LenMax = FormatMeta(Timer.meta[j],0).length + 2; \n "
" if(Len > MetaLengths[j]) \n "
" { \n "
" MetaLengths[j] = Len; \n "
" } \n "
" if(LenAvg > MetaLengthsAvg[j]) \n "
" { \n "
" MetaLengthsAvg[j] = LenAvg; \n "
" } \n "
" if(LenMax > MetaLengthsMax[j]) \n "
" { \n "
" MetaLengthsMax[j] = LenMax; \n "
" } \n "
" } \n "
" } \n "
" } \n "
" \n "
" function Preprocess() \n "
" { \n "
" var ProfileModeOld = ProfileMode; \n "
" ProfileMode = 1; \n "
" ProfileModeClear(); \n "
" ProfileEnter( \" Preprocess \" ); \n "
" PreprocessCalculateAllTimers(); \n "
" PreprocessFindFirstFrames(); \n "
" PreprocessGlobalArray(); \n "
" PreprocessLods(); \n "
" PreprocessMeta(); \n "
" PreprocessContextSwitchCache(); \n "
" ProfileLeave(); \n "
" ProfileModeDump(); \n "
" ProfileMode = ProfileModeOld; \n "
" Initialized = 1; \n "
" } \n "
" \n "
" InitGroups(); \n "
" ReadCookie(); \n "
" MeasureFont() \n "
" InitThreadMenu(); \n "
" InitGroupMenu(); \n "
" InitFrameInfo(); \n "
" UpdateThreadMenu(); \n "
" ResizeCanvas(); \n "
" Preprocess(); \n "
" OnPageReady(); \n "
" Draw(1); \n "
" AutoRedraw(); \n "
" \n "
" </script> \n "
" </body> \n "
" </html> " ;
const size_t g_MicroProfileHtml_end_2_size = sizeof ( g_MicroProfileHtml_end_2 ) ;
const char * g_MicroProfileHtml_end [ ] = {
& g_MicroProfileHtml_end_0 [ 0 ] ,
& g_MicroProfileHtml_end_1 [ 0 ] ,
& g_MicroProfileHtml_end_2 [ 0 ] ,
} ;
size_t g_MicroProfileHtml_end_sizes [ ] = {
sizeof ( g_MicroProfileHtml_end_0 ) ,
sizeof ( g_MicroProfileHtml_end_1 ) ,
sizeof ( g_MicroProfileHtml_end_2 ) ,
} ;
size_t g_MicroProfileHtml_end_count = 3 ;
# endif //MICROPROFILE_EMBED_HTML
///end file generated from microprofile.html