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 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(); }