// returns true if the marker is a continuation from the previous frame, and adds it to the previous marker, returns false otherwise private static bool CheckForContinuationMarker(RawFrameDataView frameData, ref AssetCaptureData captureData, int threadIndex, int markerId, int frameIndex, int sampleIndex) { ulong markerStartTimeNs = frameData.GetSampleStartTimeNs(sampleIndex); ulong sampleLengthNs = frameData.GetSampleTimeNs(sampleIndex); // if the marker is right at the start of the frame, it could have been split from another on the previous frame if (frameData.frameStartTimeNs == markerStartTimeNs) { // check for a matching marker that ends at the exact point this one starts for (int j = 0; j < captureData.m_AssetLoadMarkers.Count; j++) { if (captureData.m_AssetLoadMarkers[j].threadIndex == threadIndex && captureData.m_AssetLoadMarkers[j].markerId == markerId) { if (AbsDiff(captureData.m_AssetLoadMarkers[j].endNs, markerStartTimeNs) < 10) { captureData.m_AssetLoadMarkers[j].endNs += sampleLengthNs; captureData.m_AssetLoadMarkers[j].lengthNs += sampleLengthNs; captureData.m_AssetLoadMarkers[j].ms = captureData.m_AssetLoadMarkers[j].lengthNs * 0.000001; captureData.m_AssetLoadMarkers[j].frameCount++; captureData.m_AssetLoadMarkers[j].lastFrameIndex = frameIndex; captureData.m_AssetLoadMarkers[j].sampleIds.Add(sampleIndex); return(true); } } } } return(false); }
void ClearData() { m_AssetMarkerTreeViewState = null; m_AssetMarkerMulticolumnHeaderState = null; m_AssetMarkerTreeView = null; m_AssetMarkerMultiColumnHeader = null; m_AssetMarkerTableIsCreated = false; m_CaptureData = new AssetCaptureData(); DataPulled = false; // Once there is no data, this will not need to be called again ProfilerDriver.profileCleared -= ClearData; }
public AssetLoadingProfilerView() { m_CaptureData = new AssetCaptureData(); AddMarker("GarbageCollectAssetsProfile", AssetMarkerType.UnloadUnusedAssets, UnloadUnusedAssetsMetadataFiller, 0); AddMarker("AssetBundle.PerformAssetLoad", AssetMarkerType.AsyncLoadAsset, LoadAssetMetadataFiller, 2); AddMarker("AssetBundle.LoadAsset", AssetMarkerType.SyncLoadAsset, LoadAssetSyncMetadataFiller, 2); AddMarker("AssetBundle.Unload", AssetMarkerType.SyncUnloadBundle, UnloadBundleMetadataFiller, 1); AddMarker("AssetBundle.UnloadAsync.DestroyObjectsMainThread", AssetMarkerType.AsyncUnloadBundle, UnloadBundleMetadataFiller, 1); AddMarker("AssetBundle.LoadAssetBundle", AssetMarkerType.LoadBundle, LoadBundleMetadataFiller, 1); AddMarker("LoadSceneOperation", AssetMarkerType.LoadScene, LoadSceneMetadataFiller, 2); AddMarker("LoadFileThreaded_LoadObjects", AssetMarkerType.LoadSceneObjects, LoadSceneObjectsMetadataFiller, 1); AddMarker("ReadObjectFromSerializedFile", AssetMarkerType.ReadObject, ReadObjectMetadataFiller, 4); AddMarker("AsyncReadManager.SyncRequest", AssetMarkerType.SyncReadRequest, AsyncReadManagerMetadataFiller, 4); AddMarker("AsyncReadManager.ReadFile", AssetMarkerType.AsyncReadRequest, AsyncReadManagerMetadataFiller, 4); }
public AssetMarkerTreeView(TreeViewState treeViewState, MultiColumnHeader multicolumnHeader, AssetCaptureData captureData, AssetLoadingProfilerView assetLoadingProfilerView) : base(treeViewState, multicolumnHeader) { m_CaptureData = captureData; m_ProfilerView = assetLoadingProfilerView; // Custom setup rowHeight = kRowHeights; showAlternatingRowBackgrounds = true; showBorder = true; customFoldoutYOffset = (kRowHeights - EditorGUIUtility.singleLineHeight) * 0.5f; // center foldout in the row since we also center content. See RowGUI multicolumnHeader.canSort = true; multicolumnHeader.sortingChanged += OnSortingChanged; multicolumnHeader.visibleColumnsChanged += OnVisibleColumnsChanged; Reload(); }
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(); }