BucketValue GetFrameTimeMinusSpikes(FrameRecord fr) { /* * float profileTime = fr.m_data.m_values["totalProfileTime"]; * float frameTime = fr.m_data.m_values["frameLengthInMS"]; * frameTime = profileTime + Math.Min(frameTime - profileTime, 4.0f); // clamp "LostTime" to 4ms * float origFrameTime = frameTime; * * string basePath = "Modules"; * string valueString = "selfTimeInMS"; * CPerfStatRecordData rd = fr.FindRecordData(basePath); * * foreach (KeyValuePair<string, CPerfStatRecordData> moduleRDPair in rd.m_children) * { * foreach (KeyValuePair<string, CPerfStatRecordData> functionRDPair in moduleRDPair.Value.m_children) * { * if (!functionRDPair.Key.Contains("CFrameProfileSystem::EndFrame")) * { * string path = basePath + "/" + moduleRDPair.Key + "/" + functionRDPair.Key; * float value = functionRDPair.Value.m_values[valueString]; * * float selfTime = value; * * if (functionRDPair.Value.m_values.ContainsKey("spike") && functionRDPair.Value.m_values["spike"] == 1.0f) * frameTime -= functionRDPair.Value.m_values["selfTimeInMS"]; * else if (!m_profilerRecordDisplayInfoTree[path].m_displayed) * frameTime -= functionRDPair.Value.m_values["selfTimeInMS"]; * } * } * } * return new BucketValue(0.001f * origFrameTime, Math.Min(1.0f / (0.001f * frameTime), 30.0f)); * */ return(new BucketValue(0.0f)); }
public FrameRecord FindClosestScreenshotFrameFromFrameIdx(int idx) { int belowIdx; for (belowIdx = idx; belowIdx >= 0; belowIdx--) { FrameRecord fr = FrameRecords[belowIdx]; if (fr.ScreenshotImage != null) { break; } } int aboveIdx; for (aboveIdx = idx; aboveIdx < FrameRecords.Count; aboveIdx++) { FrameRecord fr = FrameRecords[aboveIdx]; if (fr.ScreenshotImage != null) { break; } } belowIdx = Math.Max(0, belowIdx); aboveIdx = Math.Min(belowIdx, FrameRecords.Count); int bestIdx = (idx - belowIdx) < (aboveIdx - idx) ? belowIdx : aboveIdx; return(FrameRecords[bestIdx]); }
public override void UpdateInstance(ZoneHighlighterInstance zhi, int fromIdx, int toIdx) { ZoneHighlighterInstance.XRange activeRange = zhi.ActiveRange; for (int i = fromIdx; i <= toIdx; i++) { FrameRecord fr = zhi.LogView.m_logData.FrameRecords[i]; foreach (UserMarkerLocation uml in fr.UserMarkers) { if (activeRange == null) { if (FromMarker != null && FromMarker.Matches(uml)) { activeRange = zhi.StartRange(fr); } } else { if (ToMarker != null && ToMarker.Matches(uml)) { activeRange = zhi.EndRange(fr, activeRange); } } } } }
public IEnumerable <RDIElementValue <ProfilerRDI> > GetValueEnumerator(FrameRecord fr) { List <RDIElementValue <ProfilerRDI> > elementValues = new List <RDIElementValue <ProfilerRDI> >(); AddElementValuesToList(fr, elementValues, null); return(elementValues); }
public int m_index; // the index of this UserMarkerLocation in m_fr.UserMarkers public UserMarkerLocation(UserMarker userMarker, FrameRecord fr, int index) { m_path = userMarker.Path; m_name = userMarker.Name; m_fr = fr; m_index = index; }
protected override float GetValue(FrameRecord fr, ViewFrameRecord vfr, LogView logView) { float lower = fr.Values[TypeNameLower]; float upper = fr.Values[TypeNameUpper]; return(upper - lower); }
public int FindClosestFrameIdxFromTime(float x, bool screenshotFrame) { int aboveIdx = 0; int belowIdx = 0; float startMidTime = FrameRecords.First().FrameMidTimeInS; for (int i = 0; i < FrameRecords.Count - 1; i++) { FrameRecord fr = FrameRecords[i]; if (screenshotFrame && (fr.ScreenshotImage == null)) { continue; } if (x < fr.FrameMidTimeInS - startMidTime) { aboveIdx = i; break; } belowIdx = i; } aboveIdx = Math.Max(aboveIdx, belowIdx); if (x > (FrameRecords[aboveIdx].FrameMidTimeInS - startMidTime + FrameRecords[belowIdx].FrameMidTimeInS - startMidTime) / 2.0f) { return(aboveIdx); } else { return(belowIdx); } }
public void UpdateCallstacks(FrameRecord fr) { callstackTreeView.Nodes.Clear(); if (fr == null || fr.Callstacks == null) { return; } foreach (Callstack callstack in fr.Callstacks) { bool foundExistingCallstackNode = false; foreach (TreeNode existingCallstackNode in callstackTreeView.Nodes) { int numExistingFunctions = existingCallstackNode.Nodes.Count; int numNewFunctions = callstack.m_functions.Count; if ((numExistingFunctions == numNewFunctions) && (existingCallstackNode.Text == callstack.m_tag)) { bool different = false; for (int i = 0; i < numExistingFunctions; i++) { if (existingCallstackNode.Nodes[i].Text != callstack.m_functions[i]) { different = true; break; } } if (!different) { existingCallstackNode.Tag = (int)existingCallstackNode.Tag + 1; foundExistingCallstackNode = true; break; } } } if (!foundExistingCallstackNode) { TreeNode callstackNode = new TreeNode(callstack.m_tag); callstackNode.Tag = 1; foreach (string functionName in callstack.m_functions) { callstackNode.Nodes.Add(functionName); } callstackTreeView.Nodes.Add(callstackNode); } } foreach (TreeNode callstackNode in callstackTreeView.Nodes) { callstackNode.Text += " (" + callstackNode.Tag + ")"; } }
protected override float GetValue(FrameRecord fr, ViewFrameRecord vfr, LogView logView) { OverviewRDI ordi = logView.m_logControl.m_ordiTree[TrackedPath]; IReadOnlyFRVs frvs = ordi.ValueIsPerLogView ? vfr.Values : fr.Values; float value = frvs[ordi.ValuesPath]; return((ValuesAreFPS && value != 0.0f) ? (1000.0f / value) : value); }
public XRange StartRange(FrameRecord fr) { XRange activeRange = new XRange(); activeRange.Start = fr; Ranges.Add(activeRange); return(activeRange); }
public virtual void AddFrameRecord(FrameRecord fr, List <KeyValuePair <string, EItemType> > newMetaDatas) { for (int i = 0, c = newMetaDatas.Count; i != c; ++i) { SetItemMetaData(newMetaDatas[i].Key, newMetaDatas[i].Value); } FrameRecords.Add(fr); }
protected void ClipIncompleteFrames(int fromIdx) { for (int i = fromIdx; i < FrameRecords.Count; i++) { FrameRecord fr = FrameRecords[i]; if (fr.Values.IsEmpty) //ContainsKey("/frameTimeInS")) { FrameRecords.RemoveRange(i, FrameRecords.Count - i); break; } } }
public override void AddFrameRecord(FrameRecord fr, List <KeyValuePair <string, EItemType> > newMetaDatas) { lock (this) { base.AddFrameRecord(fr, newMetaDatas); ProcessRecords(fr.Index); } foreach (LogView logView in LogViews) { logView.m_logControl.NewRecordsAvailable(); } //m_logControl.UpdateControls(fr.m_index); // change this to a listener setup? and also only do it for the views that have this log data }
public void GetFrameTimeData(int fromFrameIdx, int toFrameIdx, out float min, out float max, out float avg) { min = float.MaxValue; max = 0.0f; avg = 0.0f; for (int i = fromFrameIdx; i <= toFrameIdx; i++) { FrameRecord fr = FrameRecords[i]; float frameLengthInMS = fr.Values["/frameLengthInMS"]; min = Math.Min(min, frameLengthInMS); max = Math.Max(max, frameLengthInMS); avg += frameLengthInMS; } avg /= (toFrameIdx - fromFrameIdx + 1); }
public float AddElementValuesToList(FrameRecord fr, List <RDIElementValue <ProfilerRDI> > elementValues, List <RDIElementValue <ProfilerRDI> > nonLeafElementValues) { float value; bool isLeafNode = IsLeaf; if (isLeafNode) { value = fr.Values[LeafPath] * DisplayScale; } else { value = 0.0f; foreach (ProfilerRDI childRdi in Children) { if (childRdi.Displayed) { if (IsCollapsed) { value += childRdi.GetDrawnTotal(fr); } else { value += childRdi.AddElementValuesToList(fr, elementValues, nonLeafElementValues); } } else if (nonLeafElementValues != null) { childRdi.AddElementValuesToList(fr, null, nonLeafElementValues); } } } if (elementValues != null && (isLeafNode || IsCollapsed)) { elementValues.Add(new RDIElementValue <ProfilerRDI>(this, value)); } if (nonLeafElementValues != null && (!isLeafNode || IsCollapsed)) { nonLeafElementValues.Add(new RDIElementValue <ProfilerRDI>(this, value)); } return(value); }
public void GetFrameGroupData(int fromFrameIdx, int toFrameIdx, String[] groups, GroupsStats stats) { for (int i = fromFrameIdx; i <= toFrameIdx; i++) { FrameRecord fr = FrameRecords[i]; foreach (string key in fr.Values.Paths) { foreach (string group in groups) { if (key.Contains(group)) { if (stats.m_groupStats.Count == 0 || !stats.ContainsGroup(group)) { stats.m_groupStats.Add(group, new GroupItemStats()); } GroupItemStats groupItemStats = stats.GetGroupItemsStats(group); string itemKey = key.Substring(key.LastIndexOf('/') + 1); if (!groupItemStats.ContainsItem(itemKey)) { groupItemStats.m_groupItemStats.Add(itemKey, new Stats()); } Stats itemStats = groupItemStats.GetItemStats(itemKey); itemStats.m_min = Math.Min(itemStats.m_min, fr.Values[key]); itemStats.m_max = Math.Max(itemStats.m_max, fr.Values[key]); itemStats.m_avg += fr.Values[key]; } } } } foreach (string group in stats.m_groupStats.Keys) { foreach (string item in stats.GetGroupItemsStats(group).m_groupItemStats.Keys) { Stats itemStats = stats.GetGroupItemsStats(group).GetItemStats(item); itemStats.m_avg /= (toFrameIdx - fromFrameIdx + 1); } } }
private float GetDrawnTotal(FrameRecord fr) { if (IsLeaf) { return(fr.Values[LeafPath] * DisplayScale); } else { float total = 0.0f; foreach (ProfilerRDI child in Children) { if (child.Displayed) { total += child.GetDrawnTotal(fr); } } return(total); } }
public void CalculateLevelRanges() { FrameRecord startFR = null; string levelName = "unknown_level_name"; foreach (FrameRecord fr in FrameRecords) { foreach (UserMarkerLocation userMarkerLoc in fr.UserMarkers) { if (userMarkerLoc.IsLevelStart()) { if (startFR != null) { Console.WriteLine("Level start marker found (level name: '" + levelName + "') before previous end!"); } startFR = fr; levelName = userMarkerLoc.GetLevelName().Replace("/", " - "); // confluence doesn't like / } else if (userMarkerLoc.IsLevelEnd()) { if (startFR != null) { m_levelRanges.Add(new FrameRecordRange(levelName, startFR.Index, fr.Index)); startFR = null; } else { Console.WriteLine("Level end marker, but no start!"); } } } } if (startFR != null) { // if there's a start with no end, use the end of the log as the range end m_levelRanges.Add(new FrameRecordRange(levelName, startFR.Index, FrameRecords.Count - 1)); } }
public override void UpdateInstance(ZoneHighlighterInstance zhi, int fromIdx, int toIdx) { if (!IsValid(zhi.LogView)) { return; } ZoneHighlighterInstance.XRange activeRange = zhi.ActiveRange; FrameRecord previousFR, fr = null; ViewFrameRecord vfr; for (int i = fromIdx; i <= toIdx; i++) { previousFR = fr; fr = zhi.LogView.m_baseLogData.FrameRecords[i]; vfr = zhi.LogView.m_baseViewFRs[i]; float value = GetValue(fr, vfr, zhi.LogView); if (activeRange == null) { if (value > MinThreshold && (value < MaxThreshold || MaxThreshold == -1.0f)) { activeRange = zhi.StartRange(fr); } //activeRange = zhi.StartRange(previousFR != null ? previousFR : fr); } else { if (value < MinThreshold || (value > MaxThreshold && MaxThreshold != -1.0f)) { activeRange = zhi.EndRange(fr, activeRange); } } } }
public void ProcessDataStream() { CultureInfo decimalCulture = new CultureInfo("en-US"); Regex callstackAddressesRegex = new Regex(@"0x[0-9|a-f|A-F]*"); IIntervalSink[] ivSinks = new IIntervalSink[] { new StreamingIntervalSink(m_logData), new StreamingObjectSink(m_logData, "/Objects", 111), new StreamingTextureSink(m_logData, "/Textures", 116), }; EventReader eventReader = new EventReader(ivSinks); try { //Endian byte[] endianByte = m_logDataStream.ReadBytes(1); EEndian endian = (EEndian)endianByte[0]; m_logDataStream.SetEndian(endian); //Version UInt32 version = m_logDataStream.ReadUInt32(); if (version > STATOSCOPE_BINARY_VERSION) { throw new Exception("Binary file version mismatch"); } m_logVersion = version; //Using string pool? m_bUsingStringPool = m_logDataStream.ReadBool(); List <KeyValuePair <string, EItemType> > newmds = new List <KeyValuePair <string, EItemType> >(); FrameRecordPathCollection paths = new FrameRecordPathCollection(); while (!m_logDataStream.IsEndOfStream) { // header present if (m_logDataStream.ReadBool()) { // modules present if (m_logDataStream.ReadBool()) { ReadModules(); } ReadFormat(); } //FRAME RECORD BEGIN FrameRecordValues values = new FrameRecordValues(paths); float frameTimeInS = 0.0f; MemoryStream screenshotImage = null; List <UserMarker> userMarkers = new List <UserMarker>(); List <Callstack> callstacks = new List <Callstack>(); //check for fps or screen shot float frameTimeValue = m_logDataStream.ReadFloat(); if (frameTimeValue > 0) { frameTimeInS = (float)Convert.ToDouble(frameTimeValue, decimalCulture); } EFrameElementType type = ReadFrameElementType(); if (type == EFrameElementType.B64Texture) { //process texture int size = m_logDataStream.ReadInt32(); byte[] screenShotBytes = m_logDataStream.ReadBytes(size); screenshotImage = ImageProcessor.CreateImageStreamFromScreenshotBytes(screenShotBytes); } //On to specific data groups foreach (PerfStatLogLineDescriptor lld in m_logLineDescriptors) { //number of stats, so records have a variable number of entries, like frame profiler int nStats = m_logDataStream.ReadInt32(); for (int i = 0; i < nStats; i++) { string path = lld.m_path; foreach (PerfStatFrameElement fe in lld.m_formatElements) { if (fe.m_type == EFrameElementType.String && fe.m_name.Equals("path")) { // Replace first occurrence of "$" in path with its placeholder value string valueString = ReadString(); StringBuilder sbModifiedString = new StringBuilder(path); sbModifiedString.Replace("$", valueString, path.IndexOf("$"), 1); path = sbModifiedString.ToString(); } else { switch (fe.m_type) { case EFrameElementType.Float: { float value = m_logDataStream.ReadFloat(); string itemname = path + fe.m_name; values[itemname] += value; // += as there may be duplicate records per frame newmds.Add(new KeyValuePair <string, EItemType>(itemname, EItemType.Float)); } break; case EFrameElementType.Int: { int value = m_logDataStream.ReadInt32(); string itemname = path + fe.m_name; values[itemname] += (float)value; // += as there may be duplicate records per frame newmds.Add(new KeyValuePair <string, EItemType>(itemname, EItemType.Int)); } break; case EFrameElementType.B64Texture: throw new Exception("Screen shot in frame profiler not supported"); //break; case EFrameElementType.String: string userMarkersInitialPath = "/UserMarkers/"; string callstacksInitialPath = "/Callstacks/"; string valueString = ReadString(); if (path.StartsWith(userMarkersInitialPath)) { string pathNoEndSlash = path.TrimEnd(new char[] { '/' }); // old format compatibility UserMarker userMarker = new UserMarker(pathNoEndSlash, valueString); userMarkers.Add(userMarker); } else if (path.StartsWith(callstacksInitialPath)) { Callstack callstack = new Callstack(path.Substring(callstacksInitialPath.Length)); MatchCollection addressesMatches = callstackAddressesRegex.Matches(valueString); foreach (Match addressMatch in addressesMatches) { UInt32 address = Convert.ToUInt32(addressMatch.Value, 16); callstack.m_functions.Add(GetSymbolNameFromAddress(address)); } callstack.m_functions.Reverse(); callstacks.Add(callstack); } break; } } } } } if (version > 1) { eventReader.ReadEvents(m_logDataStream); } UInt32 magic = m_logDataStream.ReadUInt32(); if (magic != 0xdeadbeef) { throw new Exception("Frame Record is corrupt"); } for (int si = 0, sc = ivSinks.Length; si != sc; ++si) { ivSinks[si].OnFrameRecord(values); } FrameRecord fr = new FrameRecord(m_logData.FrameRecords.Count, frameTimeInS, screenshotImage, m_logData.CreateNewFrameRecordValues(values), userMarkers, callstacks); m_logData.AddFrameRecord(fr, newmds); m_logDataStream.FlushWriteStream(); newmds.Clear(); } } catch (Exception ex) { Console.WriteLine(ex); } foreach (var resolver in m_symbolResolvers) { resolver.Dispose(); } m_symbolResolvers.Clear(); m_logDataStream.CloseWriteStream(); }
protected abstract float GetValue(FrameRecord fr, ViewFrameRecord vfr, LogView logView);
public XRange EndRange(FrameRecord fr, XRange activeRange) { activeRange.End = fr; return(null); }
public void ProcessDataStream() { CultureInfo decimalCulture = new CultureInfo("en-US"); Regex callstackAddressesRegex = new Regex(@"0x[0-9|a-f|A-F]*"); List <KeyValuePair <string, EItemType> > newmds = new List <KeyValuePair <string, EItemType> >(); FrameRecordPathCollection paths = new FrameRecordPathCollection(); while (!m_logDataStream.IsEndOfStream) { if (m_logDataStream.Peek() == '<') { ReadMetaData(); continue; } if (m_logLineDescriptors.Count == 0) { m_logDataStream.ReadLine(); continue; } FrameRecordValues values = new FrameRecordValues(paths); float frameTimeInS = 0.0f; MemoryStream screenshotImage = null; List <UserMarker> userMarkers = new List <UserMarker>(); List <Callstack> callstacks = new List <Callstack>(); foreach (PerfStatLogLineDescriptor lld in m_logLineDescriptors) { string line = m_logDataStream.ReadLine(); if (line == null) { // it looks like the log's broken break; } MatchCollection lineElements = lld.m_regex.Matches(line); foreach (Match lineElement in lineElements) { string frameTimeValue = lineElement.Groups["frameTimeInS"].Value; if (frameTimeValue.Length > 0) { frameTimeInS = (float)Convert.ToDouble(frameTimeValue, decimalCulture); } string path = lld.m_path; foreach (PerfStatFrameElement fe in lld.m_formatElements) { string valueString = lineElement.Groups[fe.m_name].Value; if (fe.m_type == EFrameElementType.String) { if (!valueString.StartsWith("'") || !valueString.EndsWith("'")) { throw new Exception("strings need to be surrounded by 's"); } valueString = valueString.Substring(1, valueString.Length - 2); } if (fe.m_name.Equals("path")) { path = path.Replace("$", valueString); } else { switch (fe.m_type) { case EFrameElementType.Float: case EFrameElementType.Int: float value = string.Compare(valueString, "1.#QNAN0") == 0 ? 1.0f : (float)Convert.ToDouble(valueString, decimalCulture); string itemname = string.Intern(path + fe.m_name); values[itemname] += value; // += as there may be duplicate records per frame newmds.Add(new KeyValuePair <string, EItemType>(itemname, fe.m_type == EFrameElementType.Float ? EItemType.Float : EItemType.Int)); break; case EFrameElementType.B64Texture: if (screenshotImage != null) { throw new Exception("multiple screenshots found for a frame"); } if (valueString.Length > 0) { try { byte[] bm = Convert.FromBase64String(valueString); screenshotImage = ImageProcessor.CreateImageStreamFromScreenshotBytes(bm); } catch (System.Exception) { } } break; case EFrameElementType.String: string userMarkersInitialPath = "/UserMarkers/"; string callstacksInitialPath = "/Callstacks/"; if (path.StartsWith(userMarkersInitialPath)) { string pathNoEndSlash = path.TrimEnd(new char[] { '/' }); // old format compatibility UserMarker userMarker = new UserMarker(pathNoEndSlash, valueString); userMarkers.Add(userMarker); } else if (path.StartsWith(callstacksInitialPath)) { Callstack callstack = new Callstack(path.Substring(callstacksInitialPath.Length)); MatchCollection addressesMatches = callstackAddressesRegex.Matches(valueString); foreach (Match addressMatch in addressesMatches) { UInt32 address = Convert.ToUInt32(addressMatch.Value, 16); callstack.m_functions.Add(GetSymbolNameFromAddress(address)); } callstack.m_functions.Reverse(); callstacks.Add(callstack); } break; } } } } } FrameRecord fr = new FrameRecord(m_logData.FrameRecords.Count, frameTimeInS, screenshotImage, m_logData.CreateNewFrameRecordValues(values), userMarkers, callstacks); m_logData.AddFrameRecord(fr, newmds); } foreach (var resolver in m_symbolResolvers) { resolver.Dispose(); } m_symbolResolvers.Clear(); }
public void CalculateFrameMidTime(FrameRecord nextFR) { FrameMidTimeInS = (this.FrameTimeInS + nextFR.FrameTimeInS) / 2.0f; }
public void AddTimeLineGraph(string [] path) { float graphStartX = 400; float graphStartY = 20; float graphWidth = m_canvasWidth - graphStartX - 20; float graphHeight = (m_canvasHeight - 100) - graphStartY - 20; float timeStart = m_logData.FrameRecords[0].FrameTimeInS; float timeRange = m_logData.FrameRecords[m_logData.FrameRecords.Count - 1].FrameTimeInS - timeStart; float maxGraphValue = 0.0f; foreach (string item in path) { maxGraphValue = Math.Max(maxGraphValue, m_logData.GetPercentileValue(fr => 1000.0f / fr.Values[item], 90.0f)); // try to fit 90% of the values in } float graphScaleX = graphWidth / timeRange; float graphScaleY = graphHeight / maxGraphValue; m_page.content += "context.strokeStyle = 'rgb(0,0,0)';\n"; m_page.content += "context.beginPath();\n"; m_page.content += string.Format("context.moveTo({0}, {1});\n", graphStartX, graphStartY); m_page.content += string.Format("context.lineTo({0}, {1});\n", graphStartX, graphStartY + graphHeight); m_page.content += string.Format("context.lineTo({0}, {1});\n", graphStartX + graphWidth, graphStartY + graphHeight); m_page.content += "context.stroke();\n"; m_page.content += "context.closePath();\n"; m_page.content += GetCanvasTargetLineString(60.0f, new RGB(1.0f, 0.0f, 0.0f), graphStartX, graphStartY, graphWidth, graphHeight, graphScaleY); m_page.content += GetCanvasTargetLineString(30.0f, new RGB(0.0f, 1.0f, 0.0f), graphStartX, graphStartY, graphWidth, graphHeight, graphScaleY); m_page.content += GetCanvasTargetLineString(25.0f, new RGB(0.0f, 0.0f, 1.0f), graphStartX, graphStartY, graphWidth, graphHeight, graphScaleY); m_page.content += GetCanvasTargetLineString(20.0f, new RGB(0.9f, 0.9f, 0.0f), graphStartX, graphStartY, graphWidth, graphHeight, graphScaleY); m_page.content += GetCanvasTargetLineString(15.0f, new RGB(1.0f, 0.0f, 1.0f), graphStartX, graphStartY, graphWidth, graphHeight, graphScaleY); m_page.content += GetCanvasTargetLineString(10.0f, new RGB(0.0f, 1.0f, 1.0f), graphStartX, graphStartY, graphWidth, graphHeight, graphScaleY); m_page.content += "context.fillStyle = \"rgb(0,0,0)\";\n"; m_page.content += string.Format("context.fillText(\"{0}\", {1}, {2});\n", Math.Round(maxGraphValue, 0).ToString(), graphStartX - 20, graphStartY); m_page.content += "context.stroke();\n"; int count = 0; int r = 0; int g = 0; int b = 255; foreach (string item in path) { m_page.content += "context.strokeStyle = 'rgb(" + r + "," + g + "," + b + ")';\n"; m_page.content += "context.beginPath();\n"; m_page.content += string.Format("context.moveTo({0}, {1});\n", graphStartX, graphStartY + graphHeight); float lastPlottedX = -float.MaxValue; for (int i = 0; i < m_logData.FrameRecords.Count; i++) { FrameRecord fr = m_logData.FrameRecords[i]; float x = (fr.FrameTimeInS - timeStart) * graphScaleX + graphStartX; if (x > lastPlottedX + 1.0f) { float value = fr.Values[item]; float fps = value > 0.0f ? 1000.0f / value : 0.0f; float y = graphStartY + graphHeight - fps * graphScaleY; m_page.content += string.Format("context.lineTo({0}, {1});\n", x, y); lastPlottedX = x; } } m_page.content += "context.stroke();\n"; m_page.content += "context.closePath();\n"; m_page.content += "context.font = \"10px arial\";\n"; m_page.content += "context.fillStyle = \"rgb(0,0,0)\";\n"; m_page.content += string.Format("context.fillText(\"{0}\", {1}, {2});\n", item, 20.0f, graphStartY + graphHeight + (10 * count)); m_page.content += "context.stroke();\n"; m_page.content += "context.strokeStyle = 'rgb(" + r + "," + g + "," + b + ")';\n"; m_page.content += "context.beginPath();\n"; m_page.content += string.Format("context.moveTo({0}, {1});\n", 0.0f, graphStartY + graphHeight + (10 * count)); m_page.content += string.Format("context.lineTo({0}, {1});\n", 15.0f, graphStartY + graphHeight + (10 * count)); m_page.content += "context.stroke();\n"; m_page.content += "context.closePath();\n"; count++; r = 255; g = (255 / path.Length) * count; b = (255 / path.Length) * count; } m_page.content += "context.font = \"10px arial\";\n"; m_page.content += "context.textAlign = 'center';\n"; m_page.content += "context.fillStyle = \"rgb(0,0,0)\";\n"; m_page.content += "context.strokeStyle = 'rgb(0,0,0)';\n"; m_page.content += "context.beginPath();\n"; foreach (FrameRecordRange frr in m_logData.LevelRanges) { float startX = (m_logData.FrameRecords[frr.StartIdx].FrameTimeInS - timeStart) * graphScaleX + graphStartX; float endX = (m_logData.FrameRecords[frr.EndIdx].FrameTimeInS - timeStart) * graphScaleX + graphStartX; m_page.content += string.Format("context.moveTo({0}, {1});\n", startX, graphStartY); m_page.content += string.Format("context.lineTo({0}, {1});\n", startX, graphStartY + graphHeight); m_page.content += string.Format("context.fillText(\"{0}\", {1}, {2});\n", frr.Name, (startX + endX) / 2.0f, graphStartY + graphHeight + 10); m_page.content += string.Format("context.moveTo({0}, {1});\n", endX, graphStartY); m_page.content += string.Format("context.lineTo({0}, {1});\n", endX, graphStartY + graphHeight); } m_page.content += "context.stroke();\n"; m_page.content += "context.closePath();\n"; }
void CalculateAllocationBucketSet(string name, string path, float start, float multistep, float max, int fromIdx) { List <Bucket> buckets; AllocationBucketSet bucketSet; float bucketsize = start; if (m_bucketSets.ContainsKey(name)) { bucketSet = (AllocationBucketSet)m_bucketSets[name]; buckets = bucketSet.m_buckets; } else { buckets = new List <Bucket>(); buckets.Add(new AllocationBucket()); while (bucketsize <= max) { bucketsize *= multistep; buckets.Add(new AllocationBucket()); } bucketSet = new AllocationBucketSet(buckets); m_bucketSets.Add(name, bucketSet); } for (int i = fromIdx; i < FrameRecords.Count; i++) { FrameRecord fr = FrameRecords[i]; foreach (string valuepath in fr.Values.Paths) { if (!valuepath.StartsWith(path)) { continue; } float value = fr.Values[valuepath] / 1024.0f; int bucketIdx = 0; bucketsize = start; while (value > bucketsize && bucketsize <= max) { bucketsize *= multistep; bucketIdx++; } bucketIdx = Math.Min(bucketIdx, buckets.Count - 1); AllocationBucket bucket = buckets[bucketIdx] as AllocationBucket; bucket.m_num++; bucketSet.m_totalAllocs++; } } float begin = 0; float end = start; for (int bucketIdx = 0; bucketIdx < buckets.Count; bucketIdx++) { AllocationBucket bucket = buckets[bucketIdx] as AllocationBucket; bucket.m_numPercent = 100.0f * bucket.m_num / bucketSet.m_totalAllocs; if (bucketIdx < buckets.Count - 1) { bucket.RangeDescription = string.Format("{0:n0} - {1:n0}", begin, end); } else { bucket.RangeDescription = string.Format("{0:n0} -", begin); } begin = end; end *= multistep; } }
public void AddTimeLineGraph(string group, string item, Stats stat, float max, float target, string units) { string timeLinePath = "/" + group + "/" + item; float timeStart = m_logData.FrameRecords[0].FrameTimeInS; float timeRange = m_logData.FrameRecords[m_logData.FrameRecords.Count - 1].FrameTimeInS - timeStart; float maxGraphValue = Math.Max(stat.m_max, max) + 10.0f; float graphStartX = 50.0f; float graphStartY = 20.0f; float graphWidth = (m_canvasWidth - graphStartX) - 50.0f; float graphHeight = (m_canvasHeight - graphStartY) - 20.0f; float graphScaleX = graphWidth / timeRange; float graphScaleY = graphHeight / maxGraphValue; m_page.content += "context.strokeStyle = 'rgb(0,0,0)';\n"; m_page.content += "context.beginPath();\n"; m_page.content += string.Format("context.moveTo({0}, {1});\n", graphStartX, graphStartY); m_page.content += string.Format("context.lineTo({0}, {1});\n", graphStartX, graphStartY + graphHeight); m_page.content += string.Format("context.lineTo({0}, {1});\n", graphStartX + graphWidth, graphStartY + graphHeight); m_page.content += string.Format("context.fillText(\"{0:n0}\", {1}, {2});\n", 0, graphStartX - 15, graphStartY + graphHeight + 15); m_page.content += string.Format("context.fillText(\"{0:n0}\", {1}, {2});\n", "Time(s)", graphStartX + (graphWidth / 2), graphStartY + graphHeight + 15); m_page.content += string.Format("context.fillText(\"{0:n0}\", {1}, {2});\n", units, 0, graphStartY + (graphHeight / 2)); m_page.content += string.Format("context.fillText(\"{0:n0}\", {1}, {2});\n", (int)maxGraphValue, 0, graphStartY); m_page.content += string.Format("context.fillText(\"{0:n0}\", {1}, {2});\n", (int)timeRange, graphStartX + graphWidth, graphStartY + graphHeight + 15); m_page.content += "context.stroke();\n"; m_page.content += "context.closePath();\n"; if (target != 0.0f) { m_page.content += GetCanvasTargetLineString(target, "target", true, new RGB(0.0f, 0.0f, 1.0f), graphStartX, graphStartY, graphWidth, graphHeight, graphScaleY); } if (max != 0.0f) { m_page.content += GetCanvasTargetLineString(max, "max", true, new RGB(1.0f, 0.0f, 1.0f), graphStartX, graphStartY, graphWidth, graphHeight, graphScaleY); } m_page.content += "context.strokeStyle = 'rgb(0,0,255)';\n"; m_page.content += "context.beginPath();\n"; m_page.content += string.Format("context.moveTo({0}, {1});\n", graphStartX, graphStartY + graphHeight); float lastPlottedX = -float.MaxValue; for (int i = 0; i < m_logData.FrameRecords.Count; i++) { FrameRecord fr = m_logData.FrameRecords[i]; float x = (fr.FrameTimeInS - timeStart) * graphScaleX + graphStartX; float value = fr.Values[timeLinePath]; float y = Math.Min(graphStartY + graphHeight, graphStartY + graphHeight - (value * graphScaleY)); m_page.content += string.Format("context.lineTo({0}, {1});\n", x, y); lastPlottedX = x; } m_page.content += "context.stroke();\n"; m_page.content += "context.closePath();\n"; m_page.content += "context.font = \"10px arial\";\n"; m_page.content += "context.textAlign = 'center';\n"; m_page.content += "context.fillStyle = \"rgb(0,0,0)\";\n"; m_page.content += "context.strokeStyle = 'rgb(0,0,0)';\n"; m_page.content += "context.beginPath();\n"; foreach (FrameRecordRange frr in m_logData.LevelRanges) { float startX = (m_logData.FrameRecords[frr.StartIdx].FrameTimeInS - timeStart) * graphScaleX + graphStartX; float endX = (m_logData.FrameRecords[frr.EndIdx].FrameTimeInS - timeStart) * graphScaleX + graphStartX; m_page.content += string.Format("context.moveTo({0}, {1});\n", startX, graphStartY); m_page.content += string.Format("context.lineTo({0}, {1});\n", startX, graphStartY + graphHeight); m_page.content += string.Format("context.fillText(\"{0}\", {1}, {2});\n", frr.Name, (startX + endX) / 2.0f, graphStartY + graphHeight + 10); m_page.content += string.Format("context.moveTo({0}, {1});\n", endX, graphStartY); m_page.content += string.Format("context.lineTo({0}, {1});\n", endX, graphStartY + graphHeight); } m_page.content += "context.stroke();\n"; m_page.content += "context.closePath();\n"; }
public ProfileTotalData(FrameRecord fr, List <string> paths, MTCounter profileTotalCounter) { m_fr = fr; m_paths = paths; m_profileTotalCounter = profileTotalCounter; }
public CDIResult CreateDisplayInfo(int fromIdx, int toIdx) { CDIResult result = new CDIResult(); List <string> dontAdds = new List <string>(); dontAdds.Add("/posx"); dontAdds.Add("/posy"); dontAdds.Add("/posz"); dontAdds.Add("/rotx"); dontAdds.Add("/roty"); dontAdds.Add("/rotz"); dontAdds.Add("/frameTimeInS"); dontAdds.Add("/gpuTimeInS"); dontAdds.Add("/TexturePool"); foreach (string path in m_dataPaths.Paths.Where(p => !m_cdiProcessedPaths.Contains(p))) { m_cdiProcessedPaths.Add(path); foreach (IGraphDesc graphDesc in m_graphDescs) { if (FrameRecord.PathMatchesPattern(path, graphDesc.GetSearchPath())) { string strippedPath = path.Substring(path.IndexOf('/')); if (!path.StartsWith("/")) { throw new Exception(); } if (!dontAdds.Contains(strippedPath)) { int indexOfLastSlash = path.LastIndexOf("/"); string basePath = path.Substring(0, indexOfLastSlash); string name = path.Substring(indexOfLastSlash + 1); float displayScale = m_logControl.GetDisplayScale(strippedPath); if (graphDesc is CProfileGraphDesc) { ProfilerRDI prdi; if (m_logControl.m_prdiTree.ContainsPath(basePath)) { prdi = m_logControl.m_prdiTree[basePath]; } else { prdi = new ProfilerRDI(basePath, displayScale); } List <ProfilerRDI> newPRDIs = m_logControl.m_prdiTree.Add(prdi); result.NewPRDIs.AddRange(newPRDIs); // this is rather wasteful and needs rethinking foreach (ProfilerRDI newPRDI in newPRDIs) { CProfileGraphDesc profGD = graphDesc as CProfileGraphDesc; ProfileGraphLeafDesc desc = profGD.m_leafDescs[profGD.m_activeLeafDesc]; newPRDI.SetMetaData(desc.Name, desc.Type); } } else { OverviewRDI ordi; if (m_logControl.m_ordiTree.ContainsPath(path)) { ordi = m_logControl.m_ordiTree[path]; } else { ordi = new OverviewRDI(path, displayScale); } // default frame length to black if (path == "/frameLengthInMS") { ordi.Colour = new Statoscope.RGB(0, 0, 0); } List <OverviewRDI> newORDIs = m_logControl.m_ordiTree.Add(ordi); result.NewORDIs.AddRange(newORDIs); } } break; // find the first one that matches } } } AddValueStatsAndItemData(result.NewPRDIs, result.NewORDIs); lock (m_baseLogData) { for (int i = fromIdx; i <= toIdx; i++) { FrameRecord fr = m_baseLogData.FrameRecords[i]; foreach (UserMarkerLocation userMarkerLoc in fr.UserMarkers) { UserMarkerRDI umrdi = new UserMarkerRDI(userMarkerLoc, this); List <UserMarkerRDI> newUMRDIs = m_logControl.m_urdiTree.Add(umrdi); result.NewUMRDIs.AddRange(newUMRDIs); } } } return(result); }
void CalculateBucketSet <T>(string name, AcceptRecord acceptRecord, GetRecordValue grv, GetRecordValue grvTime, float start, float range, float max, bool lessThanMode, int fromIdx) where T : Bucket, new() { List <Bucket> buckets; TimeBucketSet bucketSet; if (m_bucketSets.ContainsKey(name)) { bucketSet = (TimeBucketSet)m_bucketSets[name]; buckets = bucketSet.m_buckets; } else { buckets = new List <Bucket>(); int numBuckets = (int)((max - start) / range) + (start == 0.0f ? 1 : 2); for (int i = 0; i < numBuckets; i++) { buckets.Add(new T()); } bucketSet = new TimeBucketSet(buckets); m_bucketSets.Add(name, bucketSet); } for (int i = fromIdx; i < FrameRecords.Count; i++) { FrameRecord fr = FrameRecords[i]; if (!acceptRecord(fr)) { continue; } float value = grv(fr); float frameTimeInMS = grvTime(fr); if (float.IsInfinity(value)) { value = 0.0f; } int offsetScaledValue = (int)((value - start) / range); int bucketIdx; if (start == 0.0f) { bucketIdx = offsetScaledValue; } else { bucketIdx = (offsetScaledValue < 0) ? 0 : (offsetScaledValue + 1); } bucketIdx = Math.Max(0, Math.Min(bucketIdx, buckets.Count - 1)); bucketIdx = buckets.Count - 1 - bucketIdx; TimeBucket bucket = buckets[bucketIdx] as TimeBucket; bucket.m_num++; bucket.m_timeInMS += frameTimeInMS; bucket.m_timeInMSClampingTo5fps += Math.Min(frameTimeInMS, 1000.0f / 5.0f); bucketSet.m_cumulativeNum++; bucketSet.m_cumulativeTimeInMS += frameTimeInMS; bucketSet.m_cumulativeTimeInMSClampingTo5fps += Math.Min(frameTimeInMS, 1000.0f / 5.0f); } float numPercentCumulative = 0.0f; float timePercentCumulative = 0.0f; float timeClamp5PercentCumulative = 0.0f; if (lessThanMode) { numPercentCumulative = 100.0f; timePercentCumulative = 100.0f; timeClamp5PercentCumulative = 100.0f; } for (int i = 0; i < buckets.Count; i++) { TimeBucket bucket = buckets[i] as TimeBucket; bucket.m_numPercent = 100.0f * bucket.m_num / (float)bucketSet.m_cumulativeNum; bucket.m_timePercent = 100.0f * bucket.m_timeInMS / bucketSet.m_cumulativeTimeInMS; bucket.m_timeClamp5Percent = 100.0f * bucket.m_timeInMSClampingTo5fps / bucketSet.m_cumulativeTimeInMSClampingTo5fps; if (!lessThanMode) { numPercentCumulative += bucket.m_numPercent; timePercentCumulative += bucket.m_timePercent; timeClamp5PercentCumulative += bucket.m_timeClamp5Percent; } bucket.m_numPercentCumulative = numPercentCumulative; bucket.m_timePercentCumulative = timePercentCumulative; bucket.m_timeClamp5PercentCumulative = timeClamp5PercentCumulative; if (lessThanMode) { numPercentCumulative -= bucket.m_numPercent; timePercentCumulative -= bucket.m_timePercent; timeClamp5PercentCumulative -= bucket.m_timeClamp5Percent; } float begin; float end; int bucketIdx = buckets.Count - 1 - i; if (start == 0.0f) { begin = bucketIdx * range; end = (bucketIdx + 1) * range; } else { begin = (bucketIdx == 0) ? 0.0f : start + ((bucketIdx - 1) * range); end = start + (bucketIdx * range); } if (bucketIdx < buckets.Count - 1) { if (lessThanMode) { bucket.RangeDescription = string.Format("<{0:n0}", end); } else { bucket.RangeDescription = string.Format("{0:n0} - {1:n0}", begin, end); } } else { if (lessThanMode) { bucket.RangeDescription = string.Format("{0:n0}+", begin); } else { bucket.RangeDescription = string.Format("{0:n0} -", begin); } } } }