diff --git a/manual/tracy.tex b/manual/tracy.tex index b987a1335d..dcfc060f60 100644 --- a/manual/tracy.tex +++ b/manual/tracy.tex @@ -3412,6 +3412,7 @@ \subsection{Options menu} \item \emph{Source location dynamic} -- Zone color is determined by source location (function name) and depth level. \end{itemize} Enabling the \emph{Ignore custom} option will force usage of the selected zone coloring scheme, disregarding any colors set by the user in profiled code. +Enabling the \emph{Inherit parent colors} option will cause zones that have a color set by the user in the profiled code to be propagated down to the child zones, although slightly darker. \item \emph{\faRulerHorizontal{} Zone name shortening} -- controls display behavior of long zone names, which don't fit inside a zone box: \begin{itemize} \item \emph{Disabled} -- Shortening of zone names is not performed and names are always displayed in full (e.g.\ \texttt{bool ns::container::add(const float\&)}). diff --git a/profiler/src/profiler/TracyColor.hpp b/profiler/src/profiler/TracyColor.hpp index 9871267991..ec1dfe6e44 100644 --- a/profiler/src/profiler/TracyColor.hpp +++ b/profiler/src/profiler/TracyColor.hpp @@ -20,6 +20,14 @@ static tracy_force_inline uint32_t HighlightColor( uint32_t color ) ( std::min( 0xFF, ( ( ( color & 0x000000FF ) ) + V ) ) ); } +static tracy_force_inline uint32_t DarkenColorSlightly( uint32_t color ) +{ + return 0xFF000000 | + ( ( ( ( color & 0x00FF0000 ) >> 16 ) * 4 / 5 ) << 16 ) | + ( ( ( ( color & 0x0000FF00 ) >> 8 ) * 4 / 5 ) << 8 ) | + ( ( ( ( color & 0x000000FF ) ) * 4 / 5 ) ); +} + static tracy_force_inline uint32_t DarkenColor( uint32_t color ) { return 0xFF000000 | diff --git a/profiler/src/profiler/TracyTimelineDraw.hpp b/profiler/src/profiler/TracyTimelineDraw.hpp index c5aa73a31f..1e1c62d8ce 100644 --- a/profiler/src/profiler/TracyTimelineDraw.hpp +++ b/profiler/src/profiler/TracyTimelineDraw.hpp @@ -24,6 +24,7 @@ struct TimelineDraw short_ptr ev; Int48 rend; uint32_t num; + uint32_t customColor; }; diff --git a/profiler/src/profiler/TracyTimelineItemThread.cpp b/profiler/src/profiler/TracyTimelineItemThread.cpp index 08a4f44755..4458ae9b65 100644 --- a/profiler/src/profiler/TracyTimelineItemThread.cpp +++ b/profiler/src/profiler/TracyTimelineItemThread.cpp @@ -9,6 +9,7 @@ #include "TracyTimelineItemThread.hpp" #include "TracyView.hpp" #include "TracyWorker.hpp" +#include "TracyColor.hpp" namespace tracy { @@ -300,7 +301,7 @@ void TimelineItemThread::Preprocess( const TimelineContext& ctx, TaskDispatch& t else #endif { - m_depth = PreprocessZoneLevel( ctx, m_thread->timeline, 0, visible ); + m_depth = PreprocessZoneLevel( ctx, m_thread->timeline, 0, visible, 0 ); } } ); @@ -399,20 +400,20 @@ int TimelineItemThread::PreprocessGhostLevel( const TimelineContext& ctx, const } #endif -int TimelineItemThread::PreprocessZoneLevel( const TimelineContext& ctx, const Vector>& vec, int depth, bool visible ) +int TimelineItemThread::PreprocessZoneLevel( const TimelineContext& ctx, const Vector>& vec, int depth, bool visible, uint32_t parentCustomColor ) { if( vec.is_magic() ) { - return PreprocessZoneLevel>( ctx, *(Vector*)( &vec ), depth, visible ); + return PreprocessZoneLevel>( ctx, *(Vector*)( &vec ), depth, visible, parentCustomColor ); } else { - return PreprocessZoneLevel>( ctx, vec, depth, visible ); + return PreprocessZoneLevel>( ctx, vec, depth, visible, parentCustomColor ); } } template -int TimelineItemThread::PreprocessZoneLevel( const TimelineContext& ctx, const V& vec, int depth, bool visible ) +int TimelineItemThread::PreprocessZoneLevel( const TimelineContext& ctx, const V& vec, int depth, bool visible, uint32_t parentCustomColor ) { const auto vStart = ctx.vStart; const auto vEnd = ctx.vEnd; @@ -450,17 +451,30 @@ int TimelineItemThread::PreprocessZoneLevel( const TimelineContext& ctx, const V if( nt - pt >= MinVisNs ) break; nextTime = nt + MinVisNs; } - if( visible ) m_draw.emplace_back( TimelineDraw { TimelineDrawType::Folded, uint16_t( depth ), (void**)&ev, m_worker.GetZoneEnd( a(*(next-1)) ), uint32_t( next - it ) } ); + if( visible ) m_draw.emplace_back( TimelineDraw { TimelineDrawType::Folded, uint16_t( depth ), (void**)&ev, m_worker.GetZoneEnd( a(*(next-1)) ), uint32_t( next - it ), parentCustomColor } ); it = next; } else { + uint32_t customColor = m_view.GetZoneCustomColor( ev, m_thread->id ); + uint32_t childCustomColor = 0; + if( m_view.GetViewData().inheritParentColors ) + { + if( customColor != 0 ) + { + childCustomColor = DarkenColorSlightly( customColor ); + } else + { + customColor = parentCustomColor; + childCustomColor = parentCustomColor; + } + } if( ev.HasChildren() ) { - const auto d = PreprocessZoneLevel( ctx, m_worker.GetZoneChildren( ev.Child() ), depth + 1, visible ); + const auto d = PreprocessZoneLevel( ctx, m_worker.GetZoneChildren( ev.Child() ), depth + 1, visible, childCustomColor ); if( d > maxdepth ) maxdepth = d; } - if( visible ) m_draw.emplace_back( TimelineDraw { TimelineDrawType::Zone, uint16_t( depth ), (void**)&ev } ); + if( visible ) m_draw.emplace_back( TimelineDraw { TimelineDrawType::Zone, uint16_t( depth ), (void**)&ev, 0, 0, customColor } ); ++it; } } diff --git a/profiler/src/profiler/TracyTimelineItemThread.hpp b/profiler/src/profiler/TracyTimelineItemThread.hpp index a78080c8bc..19b1aa6d61 100644 --- a/profiler/src/profiler/TracyTimelineItemThread.hpp +++ b/profiler/src/profiler/TracyTimelineItemThread.hpp @@ -37,10 +37,10 @@ class TimelineItemThread final : public TimelineItem #ifndef TRACY_NO_STATISTICS int PreprocessGhostLevel( const TimelineContext& ctx, const Vector& vec, int depth, bool visible ); #endif - int PreprocessZoneLevel( const TimelineContext& ctx, const Vector>& vec, int depth, bool visible ); + int PreprocessZoneLevel( const TimelineContext& ctx, const Vector>& vec, int depth, bool visible, uint32_t parentCustomColor ); template - int PreprocessZoneLevel( const TimelineContext& ctx, const V& vec, int depth, bool visible ); + int PreprocessZoneLevel( const TimelineContext& ctx, const V& vec, int depth, bool visible, uint32_t parentCustomColor ); void PreprocessContextSwitches( const TimelineContext& ctx, const ContextSwitch& ctxSwitch, bool visible ); void PreprocessSamples( const TimelineContext& ctx, const Vector& vec, bool visible, int yPos ); diff --git a/profiler/src/profiler/TracyUserData.cpp b/profiler/src/profiler/TracyUserData.cpp index 71ba35a809..60184da94c 100644 --- a/profiler/src/profiler/TracyUserData.cpp +++ b/profiler/src/profiler/TracyUserData.cpp @@ -145,6 +145,7 @@ void UserData::LoadState( ViewData& data ) if( ini_sget( ini, "options", "drawCpuUsageGraph", "%d", &v ) ) data.drawCpuUsageGraph = v; if( ini_sget( ini, "options", "drawSamples", "%d", &v ) ) data.drawSamples = v; if( ini_sget( ini, "options", "dynamicColors", "%d", &v ) ) data.dynamicColors = v; + if( ini_sget( ini, "options", "inheritParentColors", "%d", &v ) ) data.inheritParentColors = v; if( ini_sget( ini, "options", "forceColors", "%d", &v ) ) data.forceColors = v; if( ini_sget( ini, "options", "ghostZones", "%d", &v ) ) data.ghostZones = v; if( ini_sget( ini, "options", "frameTarget", "%d", &v ) ) data.frameTarget = v; @@ -194,6 +195,7 @@ void UserData::SaveState( const ViewData& data ) fprintf( f, "drawCpuUsageGraph = %d\n", data.drawCpuUsageGraph ); fprintf( f, "drawSamples = %d\n", data.drawSamples ); fprintf( f, "dynamicColors = %d\n", data.dynamicColors ); + fprintf( f, "inheritParentColors = %d\n", data.inheritParentColors ); fprintf( f, "forceColors = %d\n", data.forceColors ); fprintf( f, "ghostZones = %d\n", data.ghostZones ); fprintf( f, "frameTarget = %d\n", data.frameTarget ); diff --git a/profiler/src/profiler/TracyView.hpp b/profiler/src/profiler/TracyView.hpp index 6f7b76de06..ffa0ab1390 100644 --- a/profiler/src/profiler/TracyView.hpp +++ b/profiler/src/profiler/TracyView.hpp @@ -308,14 +308,17 @@ class View void AddAnnotation( int64_t start, int64_t end ); +public: uint32_t GetThreadColor( uint64_t thread, int depth ); uint32_t GetSrcLocColor( const SourceLocation& srcloc, int depth ); uint32_t GetRawSrcLocColor( const SourceLocation& srcloc, int depth ); - uint32_t GetZoneColor( const ZoneEvent& ev, uint64_t thread, int depth ); + uint32_t GetZoneColor( const ZoneEvent& ev, uint64_t thread, int depth, uint32_t customColor ); + uint32_t GetZoneCustomColor( const ZoneEvent& ev, uint64_t thread ); uint32_t GetZoneColor( const GpuEvent& ev ); - ZoneColorData GetZoneColorData( const ZoneEvent& ev, uint64_t thread, int depth ); + ZoneColorData GetZoneColorData( const ZoneEvent& ev, uint64_t thread, int depth, uint32_t customColor ); ZoneColorData GetZoneColorData( const GpuEvent& ev ); +private: void ZoomToZone( const ZoneEvent& ev ); void ZoomToZone( const GpuEvent& ev ); void ZoomToPrevFrame(); @@ -331,6 +334,7 @@ class View void CallstackTooltipContents( uint32_t idx ); void CrashTooltip(); +public: const ZoneEvent* GetZoneParent( const ZoneEvent& zone ) const; const ZoneEvent* GetZoneParent( const ZoneEvent& zone, uint64_t tid ) const; const ZoneEvent* GetZoneChild( const ZoneEvent& zone, int64_t time ) const; @@ -348,6 +352,7 @@ class View const char* GetFrameSetName( const FrameData& fd ) const; static const char* GetFrameSetName( const FrameData& fd, const Worker& worker ); +private: #ifndef TRACY_NO_STATISTICS void FindZones(); void FindZonesCompare(); diff --git a/profiler/src/profiler/TracyViewData.hpp b/profiler/src/profiler/TracyViewData.hpp index d479079ed0..43ed5ee300 100644 --- a/profiler/src/profiler/TracyViewData.hpp +++ b/profiler/src/profiler/TracyViewData.hpp @@ -53,6 +53,7 @@ struct ViewData uint8_t drawCpuUsageGraph = true; uint8_t drawSamples = true; uint8_t dynamicColors = 1; + uint8_t inheritParentColors = 1; uint8_t forceColors = false; uint8_t ghostZones = true; ShortenName shortenName = ShortenName::NoSpaceAndNormalize; diff --git a/profiler/src/profiler/TracyView_Options.cpp b/profiler/src/profiler/TracyView_Options.cpp index 6a7f7ad300..e17d76655d 100644 --- a/profiler/src/profiler/TracyView_Options.cpp +++ b/profiler/src/profiler/TracyView_Options.cpp @@ -225,6 +225,9 @@ void View::DrawOptions() ImGui::SameLine(); bool forceColors = m_vd.forceColors; if( SmallCheckbox( "Ignore custom", &forceColors ) ) m_vd.forceColors = forceColors; + ImGui::SameLine(); + bool inheritColors = m_vd.inheritParentColors; + if( SmallCheckbox( "Inherit parent colors", &inheritColors ) ) m_vd.inheritParentColors = inheritColors; ImGui::Indent(); ImGui::PushStyleVar( ImGuiStyleVar_FramePadding, ImVec2( 0, 0 ) ); ImGui::RadioButton( "Static", &ival, 0 ); diff --git a/profiler/src/profiler/TracyView_Utility.cpp b/profiler/src/profiler/TracyView_Utility.cpp index e341de599b..ce5060ba35 100644 --- a/profiler/src/profiler/TracyView_Utility.cpp +++ b/profiler/src/profiler/TracyView_Utility.cpp @@ -41,20 +41,29 @@ uint32_t View::GetSrcLocColor( const SourceLocation& srcloc, int depth ) return GetRawSrcLocColor( srcloc, depth ); } -uint32_t View::GetZoneColor( const ZoneEvent& ev, uint64_t thread, int depth ) +uint32_t View::GetZoneCustomColor( const ZoneEvent& ev, uint64_t thread ) { + if( m_worker.HasZoneExtra( ev ) ) + { + const auto custom_color = m_worker.GetZoneExtra( ev ).color.Val(); + if( custom_color != 0 ) return custom_color | 0xFF000000; + } const auto sl = ev.SrcLoc(); const auto& srcloc = m_worker.GetSourceLocation( sl ); + const auto color = srcloc.color; + if( color != 0 ) return color | 0xFF000000; + return 0; +} + +uint32_t View::GetZoneColor( const ZoneEvent& ev, uint64_t thread, int depth, uint32_t customColor ) +{ if( !m_vd.forceColors ) { - if( m_worker.HasZoneExtra( ev ) ) - { - const auto custom_color = m_worker.GetZoneExtra( ev ).color.Val(); - if( custom_color != 0 ) return custom_color | 0xFF000000; - } - const auto color = srcloc.color; - if( color != 0 ) return color | 0xFF000000; + // First check if the zone itself has a color, before we fetch the chain-of-parents, which is expensive to do. + if( customColor != 0 ) return customColor | 0xFF000000; } + const auto sl = ev.SrcLoc(); + const auto& srcloc = m_worker.GetSourceLocation( sl ); switch( m_vd.dynamicColors ) { case 0: @@ -76,27 +85,27 @@ uint32_t View::GetZoneColor( const GpuEvent& ev ) return color != 0 ? ( color | 0xFF000000 ) : 0xFF222288; } -View::ZoneColorData View::GetZoneColorData( const ZoneEvent& ev, uint64_t thread, int depth ) +View::ZoneColorData View::GetZoneColorData( const ZoneEvent& ev, uint64_t thread, int depth, uint32_t customColor ) { ZoneColorData ret; const auto& srcloc = ev.SrcLoc(); if( m_zoneInfoWindow == &ev ) { - ret.color = GetZoneColor( ev, thread, depth ); + ret.color = GetZoneColor( ev, thread, depth, customColor ); ret.accentColor = 0xFF44DD44; ret.thickness = 3.f; ret.highlight = true; } else if( m_zoneHighlight == &ev ) { - ret.color = GetZoneColor( ev, thread, depth ); + ret.color = GetZoneColor( ev, thread, depth, customColor ); ret.accentColor = 0xFF4444FF; ret.thickness = 3.f; ret.highlight = true; } else if( m_zoneSrcLocHighlight == srcloc ) { - ret.color = GetZoneColor( ev, thread, depth ); + ret.color = GetZoneColor( ev, thread, depth, customColor ); ret.accentColor = 0xFFEEEEEE; ret.thickness = 1.f; ret.highlight = true; @@ -119,7 +128,7 @@ View::ZoneColorData View::GetZoneColorData( const ZoneEvent& ev, uint64_t thread } else { - const auto color = GetZoneColor( ev, thread, depth ); + const auto color = GetZoneColor( ev, thread, depth, customColor ); ret.color = color; ret.accentColor = HighlightColor( color ); ret.thickness = 1.f; diff --git a/profiler/src/profiler/TracyView_ZoneTimeline.cpp b/profiler/src/profiler/TracyView_ZoneTimeline.cpp index e3ebdd98e7..f87ff79a81 100644 --- a/profiler/src/profiler/TracyView_ZoneTimeline.cpp +++ b/profiler/src/profiler/TracyView_ZoneTimeline.cpp @@ -223,7 +223,7 @@ void View::DrawZoneList( const TimelineContext& ctx, const std::vector