From a27d23524c09fdd7b7de0ebbcf87a769e9955586 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 4 May 2022 16:02:07 +0000 Subject: [PATCH] Consistently print fixed-width percentages. --- server/TracyPrint.hpp | 59 +++++++++++++++++++++ server/TracySourceView.cpp | 102 +++++-------------------------------- 2 files changed, 71 insertions(+), 90 deletions(-) diff --git a/server/TracyPrint.hpp b/server/TracyPrint.hpp index 0ec4b416..de001f83 100644 --- a/server/TracyPrint.hpp +++ b/server/TracyPrint.hpp @@ -26,6 +26,7 @@ #include #include +#include #include "../common/TracyForceInline.hpp" @@ -77,6 +78,42 @@ static tracy_force_inline void RealToStringInteger( char* buf, char* end ) } } +template +int DigitsLeftOfDecimalPoint( T val ) { + int digits = 1; + T absVal = std::abs( val ); + T maxAbsValForCurrentDigits = 10; + while( absVal >= maxAbsValForCurrentDigits ) { + ++digits; + maxAbsValForCurrentDigits *= static_cast( 10 ); + } + return digits; +} + +template +int CharsLeftOfDecimalPoint( T val ) { + int extraChars = std::signbit( val ) ? 1 : 0; + return extraChars + DigitsLeftOfDecimalPoint( val ); +} + +template +int DigitsRightOfDecimalPoint( T val, int maxChars ) { + int charsLeftOfPoint = CharsLeftOfDecimalPoint( val ); + if( charsLeftOfPoint > maxChars ) { + fprintf( stderr, "Maximum of %d chars is insufficient to print value %g\n", + maxChars, val ); + abort(); + } + if ( charsLeftOfPoint == maxChars ) { + // maxChars is just large enough for the integer part, no room left for + // a decimal point. + return 0; + } else { + assert( charsLeftOfPoint < maxChars ); + return maxChars - 1 - charsLeftOfPoint; + } +} + } template @@ -99,6 +136,28 @@ static inline char* PrintFloat( char* begin, char* end, T value ) #endif } +// Similar to PrintFloat, but prints exactly `fixedWidth` characters, +// right-justified. +template +char* PrintFloatFixedWidth( char* begin, char* end, T value, int fixedWidth ) { + int digitsRight = detail::DigitsRightOfDecimalPoint( value, fixedWidth ); + char buf[32]; + char* bufEnd = buf + sizeof buf; + char* printEnd = PrintFloat( buf, bufEnd, value, digitsRight ); + int width = printEnd - buf; + assert( width <= fixedWidth ); + char* dstPtr = begin; + for( int i = width; i < fixedWidth; ++i ) { + assert( end > begin ); + *dstPtr++ = ' '; + } + assert( end > dstPtr + width ); + memcpy( dstPtr, buf, width ); + dstPtr += width; + assert(dstPtr == begin + fixedWidth); + return dstPtr; +} + #ifndef NO_CHARCONV template static inline const char* RealToString( T val ) diff --git a/server/TracySourceView.cpp b/server/TracySourceView.cpp index fd749c34..08129379 100644 --- a/server/TracySourceView.cpp +++ b/server/TracySourceView.cpp @@ -2873,6 +2873,14 @@ static bool PrintPercentage( float val, uint32_t col = 0xFFFFFFFF ) return ImGui::IsWindowHovered() && ImGui::IsMouseHoveringRect( wpos, wpos + ImVec2( stw * 7, ty ) ); } +static void PrintPercentageUnformattedFixedWidth( float val, uint32_t col ) +{ + char buf[16]; + char *afterFloat = PrintFloatFixedWidth( buf, buf + sizeof buf, val, 4 ); + memcpy( afterFloat, "% ", 3 ); + TextColoredUnformatted( col, buf ); +} + void SourceView::RenderLine( const Tokenizer::Line& line, int lineNum, const AddrStat& ipcnt, const AddrStatData& as, Worker* worker, const View* view ) { const auto scale = GetScale(); @@ -4174,27 +4182,7 @@ void SourceView::RenderHwLinePart( size_t cycles, size_t retired, size_t branchR { const float rate = float( branchRel ) / branchRelMax; uint32_t col = GetGoodnessColor( 1.f - rate * 3.f ); - if( rate >= 1.f ) - { - TextColoredUnformatted( col, " 100% " ); - } - else - { - char buf[16]; - if( rate >= 0.1f ) - { - const auto end = PrintFloat( buf, buf+16, rate * 100, 1 ); - assert( end == buf+4 ); - } - else - { - *buf = ' '; - const auto end = PrintFloat( buf+1, buf+16, rate * 100, 1 ); - assert( end == buf+4 ); - } - memcpy( buf+4, "% ", 3 ); - TextColoredUnformatted( col, buf ); - } + PrintPercentageUnformattedFixedWidth( rate * 100.f, col ); if( ImGui::IsItemHovered() ) { UnsetFont(); @@ -4218,25 +4206,7 @@ void SourceView::RenderHwLinePart( size_t cycles, size_t retired, size_t branchR { const float rate = float( cacheRel ) / cacheRelMax; uint32_t col = GetGoodnessColor( 1.f - rate * 3.f ); - if( rate >= 1.f ) - { - TextColoredUnformatted( col, " 100%" ); - } - else - { - char buf[16]; - const auto end = PrintFloat( buf, buf+16, rate * 100, 1 ); - memcpy( end, "%", 2 ); - if( end - buf == 4 ) - { - TextColoredUnformatted( col, buf ); - } - else - { - ImGui::SameLine( 0, ts.x ); - TextColoredUnformatted( col, buf ); - } - } + PrintPercentageUnformattedFixedWidth( rate * 100.f, col ); if( ImGui::IsItemHovered() ) { UnsetFont(); @@ -4263,31 +4233,7 @@ void SourceView::RenderHwLinePart( size_t cycles, size_t retired, size_t branchR const bool unreliable = branchRetired < 10; const float rate = float( branchMiss ) / branchRetired; uint32_t col = unreliable ? 0x44FFFFFF : GetGoodnessColor( 1.f - rate * 3.f ); - if( branchMiss == 0 ) - { - TextColoredUnformatted( col, " 0% " ); - } - else if( rate >= 1.f ) - { - TextColoredUnformatted( col, " 100% " ); - } - else - { - char buf[16]; - if( rate >= 0.1f ) - { - const auto end = PrintFloat( buf, buf+16, rate * 100, 1 ); - assert( end == buf+4 ); - } - else - { - *buf = ' '; - const auto end = PrintFloat( buf+1, buf+16, rate * 100, 1 ); - assert( end == buf+4 ); - } - memcpy( buf+4, "% ", 3 ); - TextColoredUnformatted( col, buf ); - } + PrintPercentageUnformattedFixedWidth( rate * 100.f, col ); if( ImGui::IsItemHovered() ) { UnsetFont(); @@ -4313,31 +4259,7 @@ void SourceView::RenderHwLinePart( size_t cycles, size_t retired, size_t branchR const bool unreliable = cacheRef < 10; const float rate = float( cacheMiss ) / cacheRef; uint32_t col = unreliable ? 0x44FFFFFF : GetGoodnessColor( 1.f - rate * 3.f ); - if( cacheMiss == 0 ) - { - TextColoredUnformatted( col, " 0%" ); - } - else if( rate >= 1.f ) - { - TextColoredUnformatted( col, " 100%" ); - } - else - { - char buf[16]; - if( rate >= 0.1f ) - { - const auto end = PrintFloat( buf, buf+16, rate * 100, 1 ); - assert( end == buf+4 ); - } - else - { - *buf = ' '; - const auto end = PrintFloat( buf+1, buf+16, rate * 100, 1 ); - assert( end == buf+4 ); - } - memcpy( buf+4, "%", 2 ); - TextColoredUnformatted( col, buf ); - } + PrintPercentageUnformattedFixedWidth( rate * 100.f, col ); if( ImGui::IsItemHovered() ) { UnsetFont();