private SampleData GetPhysicsSampleData(RawFrameDataView frameData, string markerName) { SampleData sampleData = default; // Find the marker. if (m_Markers.TryGetValue(markerName, out int markerId)) { for (var i = 0; i < frameData.sampleCount; ++i) { // Ignore if it's not the marker we want. if (markerId != frameData.GetSampleMarkerId(i)) { continue; } // Accumulate sample data. sampleData.timeMs += frameData.GetSampleTimeMs(i); sampleData.count++; } } return(sampleData); }
int FindFirstMatchingRawSampleIndexInScopeRecursively(RawFrameDataView frameData, ref List <int> sampleIndexPath, string sampleName, int sampleMarkerId = FrameDataView.invalidMarkerId) { if (sampleMarkerId == FrameDataView.invalidMarkerId) { sampleMarkerId = frameData.GetMarkerId(sampleName); } var firstIndex = sampleIndexPath != null && sampleIndexPath.Count > 0 ? sampleIndexPath[sampleIndexPath.Count - 1] : 0; var lastSampleInSearchScope = firstIndex == 0 ? frameData.sampleCount - 1 : firstIndex + frameData.GetSampleChildrenCountRecursive(firstIndex); // Check if the enclosing scope matches the searched sample if (sampleIndexPath != null && sampleIndexPath.Count > 0 && (sampleMarkerId == FrameDataView.invalidMarkerId && GetItemName(frameData, firstIndex) == sampleName || frameData.GetSampleMarkerId(firstIndex) == sampleMarkerId)) { return(firstIndex); } var samplePathAndLastSampleInScope = new List <RawSampleIterationInfo>() { }; for (int i = firstIndex; i <= lastSampleInSearchScope; i++) { samplePathAndLastSampleInScope.Add(new RawSampleIterationInfo { sampleIndex = i, lastSampleIndexInScope = i + frameData.GetSampleChildrenCountRecursive(i) }); if (sampleMarkerId == FrameDataView.invalidMarkerId && (sampleName != null && GetItemName(frameData, i) == sampleName) || frameData.GetSampleMarkerId(i) == sampleMarkerId) { // ignore the first sample if it's the enclosing sample (which is already in the list) for (int j = sampleIndexPath.Count > 0 ? 1 : 0; j < samplePathAndLastSampleInScope.Count; j++) { // ignore the first sample if it's either the thread root sample. // we can't always assume that there is a thread root sample, as the data may be mal formed, but we need to check if this is one by checking the name if (j == 0 && frameData.GetSampleName(samplePathAndLastSampleInScope[j].sampleIndex) == frameData.threadName) { continue; } sampleIndexPath.Add(samplePathAndLastSampleInScope[j].sampleIndex); } return(i); } while (samplePathAndLastSampleInScope.Count > 0 && i + 1 > samplePathAndLastSampleInScope[samplePathAndLastSampleInScope.Count - 1].lastSampleIndexInScope) { samplePathAndLastSampleInScope.RemoveAt(samplePathAndLastSampleInScope.Count - 1); } } return(RawFrameDataView.invalidSampleIndex); }
int FindMarkerPathAndRawSampleIndexToFirstMatchingSampleInCurrentView(int frameIndex, int threadIndex, ref string sampleName, ref List <int> markerIdPath, string markerNamePath = null, int sampleMarkerId = FrameDataView.invalidMarkerId) { using (var frameData = new RawFrameDataView(frameIndex, threadIndex)) { List <int> tempMarkerIdPath = null; if (markerIdPath != null && markerIdPath.Count > 0) { tempMarkerIdPath = markerIdPath; } var foundSampleIndex = RawFrameDataView.invalidSampleIndex; var sampleIndexPath = new List <int>(); if (sampleMarkerId == FrameDataView.invalidMarkerId) { sampleMarkerId = frameData.GetMarkerId(sampleName); } int pathLength = 0; string lastSampleInPath = null; Func <int, int, RawFrameDataView, bool> sampleIdFitsMarkerPathIndex = null; if (tempMarkerIdPath != null && tempMarkerIdPath.Count > 0) { pathLength = tempMarkerIdPath.Count; } else if (!string.IsNullOrEmpty(markerNamePath)) { var path = markerNamePath.Split('/'); if (path != null && path.Length > 0) { pathLength = path.Length; using (var iterator = new RawFrameDataView(frameIndex, threadIndex)) { tempMarkerIdPath = new List <int>(pathLength); for (int i = 0; i < pathLength; i++) { tempMarkerIdPath.Add(iterator.GetMarkerId(path[i])); } } sampleIdFitsMarkerPathIndex = (sampleIndex, markerPathIndex, iterator) => { return(tempMarkerIdPath[markerPathIndex] == FrameDataView.invalidMarkerId && GetItemName(iterator, sampleIndex) == path[markerPathIndex]); }; } } if (pathLength > 0) { var enclosingScopeSampleIndex = RawFrameDataView.invalidSampleIndex; if (sampleIndexPath.Capacity < pathLength) { sampleIndexPath.Capacity = pathLength + 1; // +1 for the presumably often case of the searched sample being part of the path or in the last scope of it } enclosingScopeSampleIndex = ProfilerTimelineGUI.FindNextSampleThroughMarkerPath( frameData, this, tempMarkerIdPath, pathLength, ref lastSampleInPath, ref sampleIndexPath, sampleIdFitsMarkerPathIndex: sampleIdFitsMarkerPathIndex); if (enclosingScopeSampleIndex == RawFrameDataView.invalidSampleIndex) { //enclosing scope not found return(RawFrameDataView.invalidSampleIndex); } foundSampleIndex = FindFirstMatchingRawSampleIndexInScopeRecursively(frameData, ref sampleIndexPath, sampleName, sampleMarkerId); while (foundSampleIndex == RawFrameDataView.invalidSampleIndex && enclosingScopeSampleIndex != RawFrameDataView.invalidSampleIndex) { // sample wasn't found in the current scope, find the next scope ... enclosingScopeSampleIndex = ProfilerTimelineGUI.FindNextSampleThroughMarkerPath( frameData, this, tempMarkerIdPath, pathLength, ref lastSampleInPath, ref sampleIndexPath, sampleIdFitsMarkerPathIndex: sampleIdFitsMarkerPathIndex); if (enclosingScopeSampleIndex == RawFrameDataView.invalidSampleIndex) { return(RawFrameDataView.invalidSampleIndex); } // ... and search there foundSampleIndex = FindFirstMatchingRawSampleIndexInScopeRecursively(frameData, ref sampleIndexPath, sampleName, sampleMarkerId); } } else { if (sampleMarkerId == FrameDataView.invalidMarkerId) { foundSampleIndex = FindFirstMatchingRawSampleIndexInScopeRecursively(frameData, ref sampleIndexPath, sampleName); } else { foundSampleIndex = FindFirstMatchingRawSampleIndexInScopeRecursively(frameData, ref sampleIndexPath, null, sampleMarkerId); } } if (foundSampleIndex != RawFrameDataView.invalidSampleIndex) { if (string.IsNullOrEmpty(sampleName)) { sampleName = GetItemName(frameData, foundSampleIndex); } if (markerIdPath == null) { markerIdPath = new List <int>(sampleIndexPath.Count); } // populate marker id path with missing markers for (int i = markerIdPath.Count; i < sampleIndexPath.Count; i++) { markerIdPath.Add(frameData.GetSampleMarkerId(sampleIndexPath[i])); } } return(foundSampleIndex); } }
ProfileData GetDataRaw(ProfileData data, int firstFrameIndex, int lastFrameIndex) { bool firstError = true; data.SetFrameIndexOffset(firstFrameIndex); var depthStack = new Stack <int>(); var threadNameCount = new Dictionary <string, int>(); var markerIdToNameIndex = new Dictionary <int, int>(); for (int frameIndex = firstFrameIndex; frameIndex <= lastFrameIndex; ++frameIndex) { m_progressBar.AdvanceProgressBar(); int threadIndex = 0; threadNameCount.Clear(); ProfileFrame frame = null; while (true) { using (RawFrameDataView frameData = ProfilerDriver.GetRawFrameDataView(frameIndex, threadIndex)) { if (threadIndex == 0) { frame = new ProfileFrame(); if (frameData.valid) { frame.msStartTime = frameData.frameStartTimeMs; frame.msFrame = frameData.frameTimeMs; } data.Add(frame); } if (!frameData.valid) { break; } string threadNameWithIndex = null; string threadName = frameData.threadName; if (threadName.Trim() == "") { Debug.Log(string.Format("Warning: Unnamed thread found on frame {0}. Corrupted data suspected, ignoring frame", frameIndex)); threadIndex++; continue; } var groupName = frameData.threadGroupName; threadName = ProfileData.GetThreadNameWithGroup(threadName, groupName); int nameCount = 0; threadNameCount.TryGetValue(threadName, out nameCount); threadNameCount[threadName] = nameCount + 1; threadNameWithIndex = ProfileData.ThreadNameWithIndex(threadNameCount[threadName], threadName); var thread = new ProfileThread(); data.AddThreadName(threadNameWithIndex, thread); frame.Add(thread); // The markers are in depth first order depthStack.Clear(); // first sample is the thread name for (int i = 1; i < frameData.sampleCount; i++) { float durationMS = frameData.GetSampleTimeMs(i); int markerId = frameData.GetSampleMarkerId(i); if (durationMS < 0) { if (firstError) { int displayIndex = data.OffsetToDisplayFrame(frameIndex); string name = frameData.GetSampleName(i); Debug.LogFormat("Ignoring Invalid marker time found for {0} on frame {1} on thread {2} ({3} < 0)", name, displayIndex, threadName, durationMS); firstError = false; } } else { int depth = 1 + depthStack.Count; var markerData = ProfileMarker.Create(durationMS, depth); // Use name index directly if we have already stored this named marker before int nameIndex; if (markerIdToNameIndex.TryGetValue(markerId, out nameIndex)) { markerData.nameIndex = nameIndex; } else { string name = frameData.GetSampleName(i); data.AddMarkerName(name, markerData); markerIdToNameIndex[markerId] = markerData.nameIndex; } thread.AddMarker(markerData); } int childrenCount = frameData.GetSampleChildrenCount(i); if (childrenCount > 0) { depthStack.Push(childrenCount); } else { while (depthStack.Count > 0) { int remainingChildren = depthStack.Pop(); if (remainingChildren > 1) { depthStack.Push(remainingChildren - 1); break; } } } } } threadIndex++; } } data.Finalise(); return(data); }
public static void PullDataStatic(ref FileAccessCaptureData captureData, Dictionary <string, FileAccessMarkerInfo> markers, ref Dictionary <string, int> markerToIDMap, int firstFrameIndex, int lastFrameIndex) { string error = null; captureData.m_FileAccessData.Clear(); captureData.m_StartTimeNs = ulong.MaxValue; captureData.m_EndTimeNs = ulong.MinValue; ProfilerFrameDataIterator frameIter = new ProfilerFrameDataIterator(); double nsFrameStart; for (int frameIndex = firstFrameIndex; frameIndex <= lastFrameIndex; ++frameIndex) { frameIter.SetRoot(frameIndex, 0); int threadCount = frameIter.GetThreadCount(frameIndex); // iterate over the threads for (int threadIndex = 0; threadIndex < threadCount; ++threadIndex) { using (RawFrameDataView frameData = ProfilerDriver.GetRawFrameDataView(frameIndex, threadIndex)) { if (!frameData.valid) { break; } nsFrameStart = frameData.frameStartTimeNs; if (frameIndex == firstFrameIndex) { if (captureData.m_StartTimeNs > nsFrameStart) { captureData.m_StartTimeNs = nsFrameStart; } } GetMarkerIDs(frameData, markers, ref markerToIDMap); string fullThreadName = GetFullThreadName(frameData.threadGroupName, frameData.threadName); // iterate over the samples to collect up any markers int sampleCount = frameData.sampleCount; for (int i = 0; i < sampleCount; ++i) { s_CheckSamples.Begin(); int markerId = frameData.GetSampleMarkerId(i); if (markerId == FrameDataView.invalidMarkerId || !markerToIDMap.ContainsValue(markerId)) { s_CheckSamples.End(); continue; } string markerName = frameData.GetMarkerName(markerId); Assert.IsTrue(markers.ContainsKey(markerName), string.Format("Marker {0} is not present in requested markers.", markerName)); s_CheckSamples.End(); s_AddNewMarker.Begin(); ulong markerStartTimeNs = Math.Max(frameData.GetSampleStartTimeNs(i) - (ulong)captureData.m_StartTimeNs, 0); ulong sampleLengthNs = frameData.GetSampleTimeNs(i); // if the marker isn't a continuation of a previous marker, add a new access if (!CheckForContinuationMarker(frameData, ref captureData, threadIndex, markerId, frameIndex, i, markerStartTimeNs, sampleLengthNs)) { FileAccessMarker fileAccessMarker = new FileAccessMarker(frameIndex, threadIndex, i); // fill in contexts from Metadata FileAccessMarkerInfo markerInfo = markers[markerName]; if (markerInfo.metadataCount == frameData.GetSampleMetadataCount(i)) { markerInfo.metaDataFiller(ref fileAccessMarker, frameData, i); } else if (error == null) // Check the error is only shown once { error = $"Some markers, such as '{markerName}', have unexpected metadata. This may be because of opening a profile captured with an older version of Unity. Certain values may be missing."; Debug.LogWarning(error); } if (string.IsNullOrEmpty(fileAccessMarker.filename)) { fileAccessMarker.readablePath = "Unknown path"; fileAccessMarker.readableFileName = "?"; } else { fileAccessMarker.readablePath = fileAccessMarker.filename; fileAccessMarker.readableFileName = Path.GetFileName(fileAccessMarker.readablePath); if (fileAccessMarker.readablePath.Contains("/Analytics/")) { fileAccessMarker.readableFileName += " (Analytics)"; } } fileAccessMarker.startNs = markerStartTimeNs; fileAccessMarker.lengthNs = sampleLengthNs; fileAccessMarker.endNs = markerStartTimeNs + sampleLengthNs; fileAccessMarker.startTimeMs = markerStartTimeNs * 0.000001; fileAccessMarker.ms = fileAccessMarker.lengthNs * 0.000001; fileAccessMarker.markerId = markerId; fileAccessMarker.type = markerInfo.fileAccessType; fileAccessMarker.markerName = markerName; fileAccessMarker.threadName = fullThreadName; fileAccessMarker.threadId = frameData.threadId; captureData.m_FileAccessData.Add(fileAccessMarker); } s_AddNewMarker.End(); } } } } foreach (var fileAccessMarker in captureData.m_FileAccessData) { fileAccessMarker.averageBandwidthMBps = (fileAccessMarker.ms > 0) ? ((float)fileAccessMarker.sizeBytes / (float)fileAccessMarker.ms) * 0.001f : 0.0f; } frameIter.Dispose(); }
public static void PullDataStatic(ref AssetCaptureData captureData, Dictionary <string, AssetMarkerInfo> markers, ref Dictionary <string, int> markerToIDMap, int firstFrameIndex, int lastFrameIndex) { string error = null; var depthStack = new Stack <int>(); captureData.m_AssetLoadMarkers.Clear(); captureData.m_StartTimeNs = ulong.MaxValue; captureData.m_EndTimeNs = ulong.MinValue; ProfilerFrameDataIterator frameIter = new ProfilerFrameDataIterator(); double nsFrameStart; for (int frameIndex = firstFrameIndex; frameIndex <= lastFrameIndex; ++frameIndex) { frameIter.SetRoot(frameIndex, 0); int threadCount = frameIter.GetThreadCount(frameIndex); // iterate over the threads for (int threadIndex = 0; threadIndex < threadCount; ++threadIndex) { using (RawFrameDataView frameData = ProfilerDriver.GetRawFrameDataView(frameIndex, threadIndex)) { if (!frameData.valid) { break; } string fullThreadName = GetFullThreadName(frameData.threadGroupName, frameData.threadName); nsFrameStart = frameData.frameStartTimeNs; if (frameIndex == firstFrameIndex) // This may only need to be done for the main thread, but does the main thread have a guaranteed index? { if (captureData.m_StartTimeNs > nsFrameStart) { captureData.m_StartTimeNs = nsFrameStart; // We will assume that this will only be true for the first frame and thus not be changed, and proceed to use this value as the start time } } GetMarkerIDs(frameData, markers, ref markerToIDMap); depthStack.Clear(); // iterate over the samples to collect up any markers int sampleCount = frameData.sampleCount; for (int i = 0; i < sampleCount; ++i) { int markerId = frameData.GetSampleMarkerId(i); if (markerId != FrameDataView.invalidMarkerId && markerToIDMap.ContainsValue(markerId)) { s_AddNewMarker.Begin(); string markerName = frameData.GetMarkerName(markerId); Assert.IsTrue(markers.ContainsKey(markerName), string.Format("Marker {0} is not present in requested markers.", markerName)); // if the marker isn't a continuation of a previous marker, add a new asset load marker if (!CheckForContinuationMarker(frameData, ref captureData, threadIndex, markerId, frameIndex, i)) { AssetLoadMarker assetLoadMarker = new AssetLoadMarker(); // fill in contexts from Metadata AssetMarkerInfo markerInfo = markers[markerName]; if (markerInfo.metadataCount == frameData.GetSampleMetadataCount(i)) { markerInfo.metaDataFiller(ref assetLoadMarker, frameData, i); } else if (string.IsNullOrEmpty(error)) // Check the error is only shown once { error = $"Some markers, such as '{markerName}', have unexpected metadata. This may be because of opening a profile captured with an older version of Unity. Certain values may be missing."; Debug.LogWarning(error); } ulong markerStartTimeNs = frameData.GetSampleStartTimeNs(i); ulong sampleLengthNs = frameData.GetSampleTimeNs(i); assetLoadMarker.markerId = markerId; if (string.IsNullOrEmpty(assetLoadMarker.filename)) { assetLoadMarker.readablePath = "Unknown path"; assetLoadMarker.readableFileName = "?"; } else { assetLoadMarker.readablePath = assetLoadMarker.filename; assetLoadMarker.readableFileName = Path.GetFileName(assetLoadMarker.readablePath); if (assetLoadMarker.readablePath.Contains("/Analytics/")) { assetLoadMarker.readableFileName += " (Analytics)"; } } assetLoadMarker.startNs = markerStartTimeNs; assetLoadMarker.lengthNs = sampleLengthNs; assetLoadMarker.endNs = markerStartTimeNs + sampleLengthNs; assetLoadMarker.startTimeMs = (markerStartTimeNs - captureData.m_StartTimeNs) * 0.000001; // could this go negative? assetLoadMarker.ms = assetLoadMarker.lengthNs * 0.000001; assetLoadMarker.frameCount = 1; assetLoadMarker.type = markerInfo.assetMarkerType; assetLoadMarker.markerName = markerName; assetLoadMarker.threadName = fullThreadName; assetLoadMarker.firstFrameIndex = frameIndex; assetLoadMarker.lastFrameIndex = frameIndex; assetLoadMarker.threadIndex = threadIndex; assetLoadMarker.threadId = frameData.threadId; assetLoadMarker.sampleIds.Add(i); assetLoadMarker.depth = 1 + depthStack.Count; captureData.m_AssetLoadMarkers.Add(assetLoadMarker); } s_AddNewMarker.End(); } UpdateDepthStack(ref depthStack, frameData.GetSampleChildrenCount(i)); } } } } frameIter.Dispose(); }