diff --git a/server/TracyTimelineDraw.hpp b/server/TracyTimelineDraw.hpp index 5c9263a9..8381d3d8 100644 --- a/server/TracyTimelineDraw.hpp +++ b/server/TracyTimelineDraw.hpp @@ -59,6 +59,13 @@ struct ContextSwitchDraw }; }; +struct SamplesDraw +{ + bool folded; + uint32_t idx; + uint32_t num; +}; + } #endif diff --git a/server/TracyTimelineItemThread.cpp b/server/TracyTimelineItemThread.cpp index 8f2e5638..c54ae71f 100644 --- a/server/TracyTimelineItemThread.cpp +++ b/server/TracyTimelineItemThread.cpp @@ -275,12 +275,14 @@ void TimelineItemThread::DrawOverlay( const ImVec2& ul, const ImVec2& dr ) void TimelineItemThread::DrawFinished() { + m_samplesDraw.clear(); m_ctxDraw.clear(); m_draw.clear(); } void TimelineItemThread::Preprocess( const TimelineContext& ctx, TaskDispatch& td ) { + assert( m_samplesDraw.empty() ); assert( m_ctxDraw.empty() ); assert( m_draw.empty() ); @@ -297,7 +299,9 @@ void TimelineItemThread::Preprocess( const TimelineContext& ctx, TaskDispatch& t } } ); - if( m_view.GetViewData().drawContextSwitches ) + const auto& vd = m_view.GetViewData(); + + if( vd.drawContextSwitches ) { auto ctxSwitch = m_worker.GetContextSwitchData( m_thread->id ); if( ctxSwitch ) @@ -307,6 +311,13 @@ void TimelineItemThread::Preprocess( const TimelineContext& ctx, TaskDispatch& t } ); } } + + if( vd.drawSamples && !m_thread->samples.empty() ) + { + td.Queue( [this, &ctx] { + PreprocessSamples( ctx, m_thread->samples ); + } ); + } } #ifndef TRACY_NO_STATISTICS @@ -538,4 +549,53 @@ void TimelineItemThread::PreprocessContextSwitches( const TimelineContext& ctx, } } +void TimelineItemThread::PreprocessSamples( const TimelineContext& ctx, const Vector& vec ) +{ + const auto vStart = ctx.vStart; + const auto vEnd = ctx.vEnd; + const auto nspx = ctx.nspx; + const auto pxns = ctx.pxns; + + const auto MinVis = 6 * GetScale(); + auto it = std::lower_bound( vec.begin(), vec.end(), vStart - 2 * MinVis * nspx, [] ( const auto& l, const auto& r ) { return l.time.Val() < r; } ); + if( it == vec.end() ) return; + const auto itend = std::lower_bound( it, vec.end(), vEnd, [] ( const auto& l, const auto& r ) { return l.time.Val() < r; } ); + if( it == itend ) return; + + while( it < itend ) + { + bool visible = true; + const auto px0 = ( it->time.Val() - vStart ) * pxns; + double px1; + auto next = it+1; + uint32_t num = 0; + if( next != itend ) + { + auto px1ns = next->time.Val() - vStart; + px1 = px1ns * pxns; + if( px1 - px0 < MinVis ) + { + const auto MinVisNs = MinVis * nspx; + visible = false; + auto nextTime = px0 + MinVisNs; + for(;;) + { + const auto prev = next; + next = std::lower_bound( next, itend, nextTime, [] ( const auto& l, const auto& r ) { return l.time.Val() < r; } ); + if( prev == next ) ++next; + if( next == itend ) break; + const auto nsnext = next->time.Val() - vStart; + if( nsnext - px1ns >= MinVisNs ) break; + px1ns = nsnext; + nextTime = next->time.Val() + nspx; + } + num = next - it; + px1 = px1ns * pxns; + } + } + m_samplesDraw.emplace_back( SamplesDraw { !visible, uint32_t( it - vec.begin() ), num } ); + it = next; + } +} + } diff --git a/server/TracyTimelineItemThread.hpp b/server/TracyTimelineItemThread.hpp index 940bb803..8edda451 100644 --- a/server/TracyTimelineItemThread.hpp +++ b/server/TracyTimelineItemThread.hpp @@ -43,10 +43,12 @@ private: int PreprocessZoneLevel( const TimelineContext& ctx, const V& vec, int depth ); void PreprocessContextSwitches( const TimelineContext& ctx, const ContextSwitch& ctxSwitch ); + void PreprocessSamples( const TimelineContext& ctx, const Vector& vec ); const ThreadData* m_thread; bool m_ghost; + std::vector m_samplesDraw; std::vector m_ctxDraw; std::vector m_draw; int m_depth;