From 8f5022c3c8eb752259efe5b407fe051661734ae7 Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Tue, 18 Apr 2023 20:28:05 +0200 Subject: [PATCH] Calculate draw lists for plots. --- server/TracyTimelineItemPlot.cpp | 119 ++++++++++++++++++++++++++++++- server/TracyTimelineItemPlot.hpp | 6 ++ 2 files changed, 124 insertions(+), 1 deletion(-) diff --git a/server/TracyTimelineItemPlot.cpp b/server/TracyTimelineItemPlot.cpp index f0018438..d6195d4e 100644 --- a/server/TracyTimelineItemPlot.cpp +++ b/server/TracyTimelineItemPlot.cpp @@ -9,8 +9,12 @@ namespace tracy { +constexpr int PlotHeightPx = 100; +constexpr int MinVisSize = 3; + + TimelineItemPlot::TimelineItemPlot( View& view, Worker& worker, PlotData* plot ) - : TimelineItem( view, worker, plot, false ) + : TimelineItem( view, worker, plot, true ) , m_plot( plot ) { } @@ -110,4 +114,117 @@ bool TimelineItemPlot::DrawContents( const TimelineContext& ctx, int& offset ) return m_view.DrawPlot( ctx, *m_plot, offset ); } +void TimelineItemPlot::DrawFinished() +{ + m_draw.clear(); +} + +void TimelineItemPlot::Preprocess( const TimelineContext& ctx, TaskDispatch& td, bool visible, int yPos ) +{ + assert( m_draw.empty() ); + + if( !visible ) return; + if( yPos > ctx.yMax ) return; + const auto PlotHeight = int( round( PlotHeightPx * GetScale() ) ); + if( yPos + PlotHeight < ctx.yMin ) return; + + td.Queue( [this, &ctx] { + const auto vStart = ctx.vStart; + const auto vEnd = ctx.vEnd; + const auto nspx = ctx.nspx; + const auto MinVisNs = int64_t( round( GetScale() * MinVisSize * nspx ) ); + + auto& vec = m_plot->data; + vec.ensure_sorted(); + if( vec.front().time.Val() > vEnd || vec.back().time.Val() < vStart ) return; + + auto it = std::lower_bound( vec.begin(), vec.end(), vStart, [] ( const auto& l, const auto& r ) { return l.time.Val() < r; } ); + auto end = std::lower_bound( it, vec.end(), vEnd, [] ( const auto& l, const auto& r ) { return l.time.Val() < r; } ); + + if( end != vec.end() ) end++; + if( it != vec.begin() ) it--; + + double min = it->val; + double max = it->val; + const auto num = end - it; + if( num > 1000000 ) + { + min = m_plot->min; + max = m_plot->max; + } + else + { + auto tmp = it; + while( ++tmp < end ) + { + if( tmp->val < min ) min = tmp->val; + else if( tmp->val > max ) max = tmp->val; + } + } + if( min == max ) + { + min--; + max++; + } + + m_plot->rMin = min; + m_plot->rMax = max; + m_plot->num = num; + + if( it == vec.begin() ) + { + m_draw.emplace_back( 0 ); + m_draw.emplace_back( it - vec.begin() ); + } + + ++it; + while( it < end ) + { + auto next = std::upper_bound( it, end, int64_t( it->time.Val() + MinVisNs ), [] ( const auto& l, const auto& r ) { return l < r.time.Val(); } ); + assert( next > it ); + const auto rsz = uint32_t( next - it ); + if( rsz == 1 ) + { + m_draw.emplace_back( 0 ); + m_draw.emplace_back( it - vec.begin() ); + ++it; + } + else + { + constexpr int NumSamples = 1024; + uint32_t samples[NumSamples]; + uint32_t cnt = 0; + uint32_t offset = it - vec.begin(); + if( rsz < NumSamples ) + { + for( cnt=0; cnt 0 ); + m_draw.emplace_back( rsz ); + m_draw.emplace_back( offset ); + m_draw.emplace_back( samples[0] ); + m_draw.emplace_back( samples[cnt-1] ); + } + } + } ); +} + } diff --git a/server/TracyTimelineItemPlot.hpp b/server/TracyTimelineItemPlot.hpp index 611c6a13..c59ac2af 100644 --- a/server/TracyTimelineItemPlot.hpp +++ b/server/TracyTimelineItemPlot.hpp @@ -2,6 +2,7 @@ #define __TRACYTIMELINEITEMPLOT_HPP__ #include "TracyEvent.hpp" +#include "TracyTimelineDraw.hpp" #include "TracyTimelineItem.hpp" namespace tracy @@ -25,11 +26,16 @@ protected: void HeaderExtraContents( const TimelineContext& ctx, int offset, float labelWidth ) override; bool DrawContents( const TimelineContext& ctx, int& offset ) override; + void DrawFinished() override; bool IsEmpty() const override; + void Preprocess( const TimelineContext& ctx, TaskDispatch& td, bool visible, int yPos ) override; + private: PlotData* m_plot; + + std::vector m_draw; }; }