diff --git a/Source/Editor/Windows/Profiler/CPU.cs b/Source/Editor/Windows/Profiler/CPU.cs index 0065b09d6..3324fddac 100644 --- a/Source/Editor/Windows/Profiler/CPU.cs +++ b/Source/Editor/Windows/Profiler/CPU.cs @@ -197,7 +197,7 @@ namespace FlaxEditor.Windows.Profiler if (_tableRowsCache == null) _tableRowsCache = new List(); - var viewRange = GetEventsViewRange(); + var viewRange = _showOnlyLastUpdateEvents ? GetMainThreadUpdateRange() : ViewRange.Full; UpdateTimeline(ref viewRange); UpdateTable(ref viewRange); } @@ -235,36 +235,27 @@ namespace FlaxEditor.Windows.Profiler } } - private ViewRange GetEventsViewRange() + private ViewRange GetMainThreadUpdateRange() { - if (_showOnlyLastUpdateEvents) + if (_events != null && _events.Count != 0) { - // Find root event named 'Update' and use it as a view range - if (_events != null && _events.Count != 0) + var threads = _events.Get(_mainChart.SelectedSampleIndex); + if (threads != null) { - var data = _events.Get(_mainChart.SelectedSampleIndex); - if (data != null) + for (int j = 0; j < threads.Length; j++) { - for (int j = 0; j < data.Length; j++) + var thread = threads[j]; + if (thread.Name != "Main" || thread.Events == null) + continue; + for (int i = 0; i < thread.Events.Length; i++) { - var events = data[j].Events; - if (events == null) - continue; - - for (int i = 0; i < events.Length; i++) - { - var e = events[i]; - - if (e.Depth == 0 && e.Name == "Update") - { - return new ViewRange(ref e); - } - } + ref var e = ref thread.Events[i]; + if (e.Depth == 0 && e.Name == "Update") + return new ViewRange(ref e); } } } } - return ViewRange.Full; } @@ -352,13 +343,28 @@ namespace FlaxEditor.Windows.Profiler // Find the first event start time (for the timeline start time) double startTime = double.MaxValue; - for (int i = 0; i < data.Length; i++) + if (viewRange.Start > 0) { - if (data[i].Events != null && data[i].Events.Length != 0) - startTime = Math.Min(startTime, data[i].Events[0].Start); + startTime = viewRange.Start; + } + else + { + var r = GetMainThreadUpdateRange(); + if (r.Start > 0) + { + startTime = r.Start; + } + else + { + for (int i = 0; i < data.Length; i++) + { + if (data[i].Events != null && data[i].Events.Length != 0) + startTime = Math.Min(startTime, data[i].Events[0].Start); + } + if (startTime >= double.MaxValue) + return 0; + } } - if (startTime >= double.MaxValue) - return 0; var container = _timeline.EventsContainer; diff --git a/Source/Engine/Profiler/ProfilerCPU.cpp b/Source/Engine/Profiler/ProfilerCPU.cpp index 0198ed7bc..417178747 100644 --- a/Source/Engine/Profiler/ProfilerCPU.cpp +++ b/Source/Engine/Profiler/ProfilerCPU.cpp @@ -24,7 +24,7 @@ ProfilerCPU::EventBuffer::~EventBuffer() DeleteArray(_data, _capacity); } -void ProfilerCPU::EventBuffer::Extract(Array& data, bool withRemove) +void ProfilerCPU::EventBuffer::Extract(Array& data, bool withRemoval) { data.Clear(); @@ -36,6 +36,13 @@ void ProfilerCPU::EventBuffer::Extract(Array& data, bool withRemove) if (count == 0) return; + // Fix iterators when buffer is full (begin == end) + if (count == capacity) + { + _count--; + count--; + } + // Find the first item (skip non-root events) Iterator firstEvent = Begin(); for (auto i = firstEvent; i.IsNotEnd(); ++i) @@ -55,7 +62,7 @@ void ProfilerCPU::EventBuffer::Extract(Array& data, bool withRemove) Iterator lastEndedRoot = End(); for (auto i = Last(); i != firstEvent; --i) { - if (i.Event().Depth == 0 && i.Event().End != 0) + if (i.Event().Depth == 0 && i.Event().End > 0) { lastEndedRoot = i; break; @@ -71,31 +78,27 @@ void ProfilerCPU::EventBuffer::Extract(Array& data, bool withRemove) const double lastRootEventEndTime = lastEndedRoot.Event().End; for (auto i = --End(); i != lastEndedRoot; --i) { - if (i.Event().End != 0 && i.Event().End <= lastRootEventEndTime) + if (i.Event().End > 0 && i.Event().End <= lastRootEventEndTime) { lastEvent = i; break; } } - if (withRemove) + if (withRemoval) { // Remove all the events between [Begin(), lastEvent] _count -= (lastEvent.Index() - Begin().Index()) & _capacityMask; } // Extract all the events between [firstEvent, lastEvent] - const int32 head = (lastEvent.Index() + 1) & _capacityMask; count = (lastEvent.Index() - firstEvent.Index() + 1) & _capacityMask; - data.Resize(count, false); - - int32 tail = (head - count) & _capacityMask; - int32 spaceLeft = capacity - tail; - int32 spaceLeftCount = Math::Min(spaceLeft, count); - int32 overflow = count - spaceLeft; - + const int32 tail = (head - count) & _capacityMask; + const int32 spaceLeft = capacity - tail; + const int32 spaceLeftCount = Math::Min(spaceLeft, count); + const int32 overflow = count - spaceLeft; Platform::MemoryCopy(data.Get(), &_data[tail], spaceLeftCount * sizeof(Event)); if (overflow > 0) Platform::MemoryCopy(data.Get() + spaceLeftCount, &_data[0], overflow * sizeof(Event)); diff --git a/Source/Engine/Profiler/ProfilerCPU.h b/Source/Engine/Profiler/ProfilerCPU.h index 000e41ccb..124082c9b 100644 --- a/Source/Engine/Profiler/ProfilerCPU.h +++ b/Source/Engine/Profiler/ProfilerCPU.h @@ -106,8 +106,8 @@ public: /// Extracts the buffer data (only ended events starting from the root level with depth=0). /// /// The output data. - /// True if also remove extracted events to prevent double-gather, false if don't modify the buffer data. - void Extract(Array& data, bool withRemove); + /// True if also remove extracted events to prevent double-gather, false if don't modify the buffer data. + void Extract(Array& data, bool withRemoval); public: /// diff --git a/Source/Engine/Profiler/ProfilingTools.cpp b/Source/Engine/Profiler/ProfilingTools.cpp index 632915048..6ce8082ba 100644 --- a/Source/Engine/Profiler/ProfilingTools.cpp +++ b/Source/Engine/Profiler/ProfilingTools.cpp @@ -57,13 +57,13 @@ void ProfilingToolsService::Update() ProfilingTools::EventsCPU.EnsureCapacity(threads.Count()); for (int32 i = 0; i < threads.Count(); i++) { - auto t = threads[i]; - if (t == nullptr) + ProfilerCPU::Thread* thread = threads[i]; + if (thread == nullptr) continue; ProfilingTools::ThreadStats* pt = nullptr; for (auto& e : ProfilingTools::EventsCPU) { - if (e.Name == t->GetName()) + if (e.Name == thread->GetName()) { pt = &e; break; @@ -72,10 +72,10 @@ void ProfilingToolsService::Update() if (!pt) { pt = &ProfilingTools::EventsCPU.AddOne(); - pt->Name = t->GetName(); + pt->Name = thread->GetName(); } - t->Buffer.Extract(pt->Events, true); + thread->Buffer.Extract(pt->Events, true); } #if 0