2019-06-22 11:40:00 +00:00
# ifdef _MSC_VER
2020-09-23 13:04:59 +00:00
# pragma warning( disable: 4267 ) // conversion from don't care to whatever, possible loss of data
2019-06-22 11:40:00 +00:00
# endif
2019-01-19 11:03:30 +00:00
# ifdef __MINGW32__
# define __STDC_FORMAT_MACROS
# endif
2017-09-14 19:28:40 +00:00
# include <algorithm>
2017-09-12 23:33:50 +00:00
# include <assert.h>
2017-09-22 20:11:30 +00:00
# include <inttypes.h>
2017-10-06 00:19:25 +00:00
# include <math.h>
2017-11-15 20:49:41 +00:00
# include <mutex>
2022-07-02 15:00:08 +00:00
# include "imgui.h"
2018-04-21 22:52:33 +00:00
# include "TracyFileRead.hpp"
2018-08-17 12:54:28 +00:00
# include "TracyFilesystem.hpp"
2022-07-02 15:00:08 +00:00
# include "TracyImGui.hpp"
2019-06-18 18:43:28 +00:00
# include "TracyPrint.hpp"
2020-03-22 19:53:59 +00:00
# include "TracySourceView.hpp"
2022-07-02 15:00:08 +00:00
# include "TracyTexture.hpp"
2017-09-12 23:33:50 +00:00
# include "TracyView.hpp"
2022-07-17 11:41:40 +00:00
# include "../public/common/TracyStackFrames.hpp"
2017-09-12 23:33:50 +00:00
2021-05-17 10:09:14 +00:00
# include "imgui_internal.h"
2020-05-03 11:29:51 +00:00
2020-11-13 16:09:57 +00:00
# ifdef _WIN32
# include <windows.h>
# elif defined __linux__
# include <sys / sysinfo.h>
# elif defined __APPLE__ || defined BSD
# include <sys / types.h>
# include <sys / sysctl.h>
# endif
2022-08-17 10:07:38 +00:00
# include "IconsFontAwesome6.h"
2018-08-17 21:22:13 +00:00
2018-07-13 21:41:12 +00:00
# ifndef M_PI_2
# define M_PI_2 1.57079632679489661923
# endif
2017-09-12 23:33:50 +00:00
namespace tracy
{
2022-07-02 10:59:25 +00:00
double s_time = 0 ;
2019-03-06 17:25:39 +00:00
2017-09-12 23:33:50 +00:00
static View * s_instance = nullptr ;
2017-11-11 21:56:05 +00:00
2022-08-12 19:44:24 +00:00
View : : View ( void ( * cbMainThread ) ( std : : function < void ( ) > , bool ) , const char * addr , uint16_t port , ImFont * fixedWidth , ImFont * smallFont , ImFont * bigFont , SetTitleCallback stcb , SetScaleCallback sscb )
2019-09-21 13:43:01 +00:00
: m_worker ( addr , port )
2017-09-30 14:58:02 +00:00
, m_staticView ( false )
2020-09-12 13:49:41 +00:00
, m_viewMode ( ViewMode : : LastFrames )
2020-10-06 16:46:36 +00:00
, m_viewModeHeuristicTry ( true )
2020-05-07 23:49:15 +00:00
, m_forceConnectionPopup ( true , true )
2018-08-04 17:47:09 +00:00
, m_frames ( nullptr )
2019-07-12 23:25:37 +00:00
, m_messagesScrollBottom ( true )
2020-08-15 00:26:35 +00:00
, m_reactToCrash ( true )
2020-11-18 00:23:46 +00:00
, m_reactToLostConnection ( true )
2019-08-16 14:02:57 +00:00
, m_smallFont ( smallFont )
2019-07-12 17:16:56 +00:00
, m_bigFont ( bigFont )
2021-03-27 12:16:19 +00:00
, m_fixedFont ( fixedWidth )
2018-08-17 15:24:18 +00:00
, m_stcb ( stcb )
2021-11-18 21:22:11 +00:00
, m_sscb ( sscb )
2019-07-26 21:05:24 +00:00
, m_userData ( )
2020-08-15 12:59:16 +00:00
, m_cbMainThread ( cbMainThread )
2017-09-21 00:10:20 +00:00
{
2017-09-12 23:33:50 +00:00
assert ( s_instance = = nullptr ) ;
s_instance = this ;
2017-09-21 00:10:20 +00:00
2020-11-13 16:09:57 +00:00
InitMemory ( ) ;
2020-03-22 19:53:59 +00:00
InitTextEditor ( fixedWidth ) ;
2017-11-11 00:39:34 +00:00
}
2022-08-12 19:44:24 +00:00
View : : View ( void ( * cbMainThread ) ( std : : function < void ( ) > , bool ) , FileRead & f , ImFont * fixedWidth , ImFont * smallFont , ImFont * bigFont , SetTitleCallback stcb , SetScaleCallback sscb )
2018-02-13 13:57:47 +00:00
: m_worker ( f )
2019-10-07 19:34:10 +00:00
, m_filename ( f . GetFilename ( ) )
2018-02-13 13:57:47 +00:00
, m_staticView ( true )
2020-09-12 13:49:41 +00:00
, m_viewMode ( ViewMode : : Paused )
2018-08-04 17:47:09 +00:00
, m_frames ( m_worker . GetFramesBase ( ) )
2019-07-12 23:25:37 +00:00
, m_messagesScrollBottom ( false )
2019-08-16 14:02:57 +00:00
, m_smallFont ( smallFont )
2019-07-12 17:16:56 +00:00
, m_bigFont ( bigFont )
2021-03-27 12:16:19 +00:00
, m_fixedFont ( fixedWidth )
2018-08-17 15:24:18 +00:00
, m_stcb ( stcb )
2021-11-18 21:22:11 +00:00
, m_sscb ( sscb )
2019-07-26 21:05:24 +00:00
, m_userData ( m_worker . GetCaptureProgram ( ) . c_str ( ) , m_worker . GetCaptureTime ( ) )
2020-08-15 12:59:16 +00:00
, m_cbMainThread ( cbMainThread )
2017-11-14 22:37:44 +00:00
{
2018-02-13 13:57:47 +00:00
assert ( s_instance = = nullptr ) ;
s_instance = this ;
2018-08-17 12:44:41 +00:00
2019-01-06 18:20:17 +00:00
m_notificationTime = 4 ;
m_notificationText = std : : string ( " Trace loaded in " ) + TimeToString ( m_worker . GetLoadTime ( ) ) ;
2020-11-13 16:09:57 +00:00
InitMemory ( ) ;
2020-03-22 19:53:59 +00:00
InitTextEditor ( fixedWidth ) ;
2018-10-21 14:03:21 +00:00
SetViewToLastFrames ( ) ;
2019-08-28 17:37:01 +00:00
m_userData . StateShouldBePreserved ( ) ;
2019-08-28 17:45:22 +00:00
m_userData . LoadState ( m_vd ) ;
2019-10-13 14:29:24 +00:00
m_userData . LoadAnnotations ( m_annotations ) ;
2020-04-18 12:25:04 +00:00
m_sourceRegexValid = m_userData . LoadSourceSubstitutions ( m_sourceSubstitutions ) ;
2020-02-01 16:49:27 +00:00
if ( m_worker . GetCallstackFrameCount ( ) = = 0 ) m_showUnknownFrames = false ;
2020-03-26 21:22:09 +00:00
if ( m_worker . GetCallstackSampleCount ( ) = = 0 ) m_showAllSymbols = true ;
2017-11-14 22:37:44 +00:00
}
2018-02-13 13:57:47 +00:00
View : : ~ View ( )
2017-09-21 23:30:57 +00:00
{
2018-02-13 13:57:47 +00:00
m_worker . Shutdown ( ) ;
2020-04-18 12:25:04 +00:00
2019-08-28 17:45:22 +00:00
m_userData . SaveState ( m_vd ) ;
2019-10-13 14:29:24 +00:00
m_userData . SaveAnnotations ( m_annotations ) ;
2020-04-18 12:25:04 +00:00
m_userData . SaveSourceSubstitutions ( m_sourceSubstitutions ) ;
2017-09-21 23:30:57 +00:00
2018-07-28 16:47:33 +00:00
if ( m_compare . loadThread . joinable ( ) ) m_compare . loadThread . join ( ) ;
2019-05-28 17:56:18 +00:00
if ( m_saveThread . joinable ( ) ) m_saveThread . join ( ) ;
2018-07-28 16:47:33 +00:00
2020-08-15 13:02:36 +00:00
if ( m_frameTexture ) FreeTexture ( m_frameTexture , m_cbMainThread ) ;
if ( m_playback . texture ) FreeTexture ( m_playback . texture , m_cbMainThread ) ;
2019-06-06 20:14:25 +00:00
2018-02-13 13:57:47 +00:00
assert ( s_instance ! = nullptr ) ;
s_instance = nullptr ;
2017-09-26 16:54:48 +00:00
}
2020-11-13 16:09:57 +00:00
void View : : InitMemory ( )
{
# ifdef _WIN32
MEMORYSTATUSEX statex ;
statex . dwLength = sizeof ( statex ) ;
GlobalMemoryStatusEx ( & statex ) ;
m_totalMemory = statex . ullTotalPhys ;
# elif defined __linux__
struct sysinfo sysInfo ;
sysinfo ( & sysInfo ) ;
m_totalMemory = sysInfo . totalram ;
# elif defined __APPLE__
size_t memSize ;
size_t sz = sizeof ( memSize ) ;
sysctlbyname ( " hw.memsize " , & memSize , & sz , nullptr , 0 ) ;
m_totalMemory = memSize ;
# elif defined BSD
size_t memSize ;
size_t sz = sizeof ( memSize ) ;
sysctlbyname ( " hw.physmem " , & memSize , & sz , nullptr , 0 ) ;
m_totalMemory = memSize ;
# else
m_totalMemory = 0 ;
# endif
}
2020-03-22 19:53:59 +00:00
void View : : InitTextEditor ( ImFont * font )
2018-08-17 12:44:41 +00:00
{
2022-08-12 19:44:24 +00:00
m_sourceView = std : : make_unique < SourceView > ( ) ;
2020-03-22 19:53:59 +00:00
m_sourceViewFile = nullptr ;
2018-08-17 12:54:28 +00:00
}
2020-04-08 00:11:58 +00:00
void View : : ViewSource ( const char * fileName , int line )
{
assert ( fileName ) ;
m_sourceViewFile = fileName ;
2020-05-23 13:14:57 +00:00
m_sourceView - > OpenSource ( fileName , line , * this , m_worker ) ;
2020-04-08 00:11:58 +00:00
}
void View : : ViewSymbol ( const char * fileName , int line , uint64_t baseAddr , uint64_t symAddr )
2018-08-17 12:54:28 +00:00
{
2020-03-27 00:47:06 +00:00
assert ( fileName | | symAddr ) ;
m_sourceViewFile = fileName ? fileName : ( const char * ) ~ uint64_t ( 0 ) ;
2020-04-17 17:17:47 +00:00
m_sourceView - > OpenSymbol ( fileName , line , baseAddr , symAddr , m_worker , * this ) ;
2018-08-17 12:44:41 +00:00
}
2020-04-08 00:11:58 +00:00
bool View : : ViewDispatch ( const char * fileName , int line , uint64_t symAddr )
2020-03-27 20:04:23 +00:00
{
2020-03-27 20:30:16 +00:00
if ( line = = 0 )
{
fileName = nullptr ;
}
else
{
2020-05-23 13:14:57 +00:00
if ( ! SourceFileValid ( fileName , m_worker . GetCaptureTime ( ) , * this , m_worker ) )
2020-03-27 20:30:16 +00:00
{
fileName = nullptr ;
line = 0 ;
}
}
2020-03-27 20:04:23 +00:00
if ( symAddr = = 0 )
{
2020-03-27 20:30:16 +00:00
if ( line ! = 0 )
{
2020-04-08 00:11:58 +00:00
ViewSource ( fileName , line ) ;
2020-03-27 20:30:16 +00:00
return true ;
}
return false ;
2020-03-27 20:04:23 +00:00
}
else
{
2020-08-14 10:38:56 +00:00
uint64_t baseAddr = 0 ;
if ( m_worker . HasSymbolCode ( symAddr ) )
{
baseAddr = symAddr ;
}
else
2020-03-27 20:04:23 +00:00
{
2020-04-08 14:55:49 +00:00
const auto parentAddr = m_worker . GetSymbolForAddress ( symAddr ) ;
2022-05-01 22:51:46 +00:00
if ( parentAddr ! = 0 & & m_worker . HasSymbolCode ( parentAddr ) )
2020-03-27 20:04:23 +00:00
{
2022-05-01 22:51:46 +00:00
baseAddr = parentAddr ;
2020-03-27 20:04:23 +00:00
}
}
2020-08-14 10:38:56 +00:00
if ( baseAddr ! = 0 | | line ! = 0 )
2020-03-27 20:30:16 +00:00
{
2020-04-08 00:11:58 +00:00
ViewSymbol ( fileName , line , baseAddr , symAddr ) ;
2020-03-27 20:30:16 +00:00
return true ;
}
return false ;
2020-03-27 20:04:23 +00:00
}
}
2021-05-15 12:25:45 +00:00
static const char * CompressionName [ ] = {
" LZ4 " ,
" LZ4 HC " ,
" LZ4 HC extreme " ,
" Zstd " ,
nullptr
} ;
static const char * CompressionDesc [ ] = {
" Fastest save, fast load time, big file size " ,
" Slow save, fastest load time, reasonable file size " ,
" Very slow save, fastest load time, file smaller than LZ4 HC " ,
" Configurable save time (fast-slowest), reasonable load time, smallest file size " ,
nullptr
} ;
static_assert ( sizeof ( CompressionName ) = = sizeof ( CompressionDesc ) , " Unmatched compression names and descriptions " ) ;
2018-04-29 23:16:08 +00:00
bool View : : Draw ( )
2017-09-15 00:30:22 +00:00
{
2018-09-09 17:28:53 +00:00
HandshakeStatus status = ( HandshakeStatus ) s_instance - > m_worker . GetHandshakeStatus ( ) ;
2019-02-12 00:41:09 +00:00
switch ( status )
2018-09-09 17:28:53 +00:00
{
2019-02-12 00:41:09 +00:00
case HandshakeProtocolMismatch :
2018-09-09 17:28:53 +00:00
ImGui : : OpenPopup ( " Protocol mismatch " ) ;
2019-02-12 00:41:09 +00:00
break ;
case HandshakeNotAvailable :
2018-09-09 17:42:06 +00:00
ImGui : : OpenPopup ( " Client not ready " ) ;
2019-02-12 00:41:09 +00:00
break ;
case HandshakeDropped :
ImGui : : OpenPopup ( " Client disconnected " ) ;
break ;
default :
break ;
2018-09-09 17:42:06 +00:00
}
2018-09-09 17:28:53 +00:00
2019-01-14 22:42:58 +00:00
const auto & failure = s_instance - > m_worker . GetFailureType ( ) ;
if ( failure ! = Worker : : Failure : : None )
{
ImGui : : OpenPopup ( " Instrumentation failure " ) ;
}
2018-09-09 17:28:53 +00:00
if ( ImGui : : BeginPopupModal ( " Protocol mismatch " , nullptr , ImGuiWindowFlags_AlwaysAutoResize ) )
{
2022-04-25 21:29:44 +00:00
ImGui : : PushFont ( s_instance - > m_bigFont ) ;
2022-08-17 10:07:38 +00:00
TextCentered ( ICON_FA_TRIANGLE_EXCLAMATION ) ;
2022-04-25 21:29:44 +00:00
ImGui : : PopFont ( ) ;
2019-02-10 01:50:34 +00:00
ImGui : : TextUnformatted ( " The client you are trying to connect to uses incompatible protocol version. \n Make sure you are using the same Tracy version on both client and server. " ) ;
2018-09-09 17:28:53 +00:00
ImGui : : Separator ( ) ;
if ( ImGui : : Button ( " My bad " ) )
{
ImGui : : CloseCurrentPopup ( ) ;
2018-09-09 17:42:06 +00:00
ImGui : : EndPopup ( ) ;
return false ;
}
2020-09-12 13:52:21 +00:00
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( " Reconnect " ) )
{
ImGui : : CloseCurrentPopup ( ) ;
ImGui : : EndPopup ( ) ;
s_instance - > m_reconnectRequested = true ;
return false ;
}
2018-09-09 17:42:06 +00:00
ImGui : : EndPopup ( ) ;
}
if ( ImGui : : BeginPopupModal ( " Client not ready " , nullptr , ImGuiWindowFlags_AlwaysAutoResize ) )
{
2022-04-25 21:29:44 +00:00
ImGui : : PushFont ( s_instance - > m_bigFont ) ;
2018-09-09 17:42:06 +00:00
TextCentered ( ICON_FA_LIGHTBULB ) ;
2022-04-25 21:29:44 +00:00
ImGui : : PopFont ( ) ;
2019-02-10 01:50:34 +00:00
ImGui : : TextUnformatted ( " The client you are trying to connect to is no longer able to sent profiling data, \n because another server was already connected to it. \n You can do the following: \n \n 1. Restart the client application. \n 2. Rebuild the client application with on-demand mode enabled. " ) ;
2018-09-09 17:42:06 +00:00
ImGui : : Separator ( ) ;
if ( ImGui : : Button ( " I understand " ) )
{
ImGui : : CloseCurrentPopup ( ) ;
2018-09-09 17:28:53 +00:00
ImGui : : EndPopup ( ) ;
return false ;
}
2020-09-12 13:52:21 +00:00
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( " Reconnect " ) )
{
ImGui : : CloseCurrentPopup ( ) ;
ImGui : : EndPopup ( ) ;
s_instance - > m_reconnectRequested = true ;
return false ;
}
2018-09-09 17:28:53 +00:00
ImGui : : EndPopup ( ) ;
}
2019-02-12 00:41:09 +00:00
if ( ImGui : : BeginPopupModal ( " Client disconnected " , nullptr , ImGuiWindowFlags_AlwaysAutoResize ) )
{
2022-04-25 21:29:44 +00:00
ImGui : : PushFont ( s_instance - > m_bigFont ) ;
2019-02-12 00:41:09 +00:00
TextCentered ( ICON_FA_HANDSHAKE ) ;
2022-04-25 21:29:44 +00:00
ImGui : : PopFont ( ) ;
2019-02-12 00:41:09 +00:00
ImGui : : TextUnformatted ( " The client you are trying to connect to has disconnected during the initial \n connection handshake. Please check your network configuration. " ) ;
ImGui : : Separator ( ) ;
if ( ImGui : : Button ( " Will do " ) )
{
ImGui : : CloseCurrentPopup ( ) ;
ImGui : : EndPopup ( ) ;
return false ;
}
2020-09-12 13:52:21 +00:00
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( " Reconnect " ) )
{
ImGui : : CloseCurrentPopup ( ) ;
ImGui : : EndPopup ( ) ;
s_instance - > m_reconnectRequested = true ;
return false ;
}
2019-02-12 00:41:09 +00:00
ImGui : : EndPopup ( ) ;
}
2019-01-14 22:42:58 +00:00
if ( ImGui : : BeginPopupModal ( " Instrumentation failure " , nullptr , ImGuiWindowFlags_AlwaysAutoResize ) )
{
const auto & data = s_instance - > m_worker . GetFailureData ( ) ;
2022-04-25 21:29:44 +00:00
ImGui : : PushFont ( s_instance - > m_bigFont ) ;
2019-01-14 22:42:58 +00:00
TextCentered ( ICON_FA_SKULL ) ;
2022-04-25 21:29:44 +00:00
ImGui : : PopFont ( ) ;
2019-02-10 01:50:34 +00:00
ImGui : : TextUnformatted ( " Profiling session terminated due to improper instrumentation. \n Please correct your program and try again. " ) ;
ImGui : : TextUnformatted ( " Reason: " ) ;
2019-01-14 22:42:58 +00:00
ImGui : : SameLine ( ) ;
2019-02-10 01:50:34 +00:00
ImGui : : TextUnformatted ( Worker : : GetFailureString ( failure ) ) ;
2019-01-14 22:42:58 +00:00
ImGui : : Separator ( ) ;
2019-01-15 17:54:41 +00:00
if ( data . srcloc ! = 0 )
2019-01-14 22:42:58 +00:00
{
2019-01-15 17:54:41 +00:00
const auto & srcloc = s_instance - > m_worker . GetSourceLocation ( data . srcloc ) ;
if ( srcloc . name . active )
{
TextFocused ( " Zone name: " , s_instance - > m_worker . GetString ( srcloc . name ) ) ;
}
TextFocused ( " Function: " , s_instance - > m_worker . GetString ( srcloc . function ) ) ;
2019-02-10 01:50:34 +00:00
TextDisabledUnformatted ( " Location: " ) ;
2019-01-15 17:54:41 +00:00
ImGui : : SameLine ( ) ;
2021-06-19 10:47:55 +00:00
ImGui : : TextUnformatted ( LocationToString ( s_instance - > m_worker . GetString ( srcloc . file ) , srcloc . line ) ) ;
2019-01-14 22:42:58 +00:00
}
2019-02-28 18:31:45 +00:00
if ( data . thread ! = 0 )
{
2019-08-27 21:08:14 +00:00
TextFocused ( " Thread: " , s_instance - > m_worker . GetThreadName ( data . thread ) ) ;
2019-02-28 18:31:45 +00:00
ImGui : : SameLine ( ) ;
2020-01-31 00:43:24 +00:00
ImGui : : TextDisabled ( " (%s) " , RealToString ( data . thread ) ) ;
2021-11-06 18:18:33 +00:00
if ( s_instance - > m_worker . IsThreadFiber ( data . thread ) )
{
ImGui : : SameLine ( ) ;
TextColoredUnformatted ( ImVec4 ( 0.2f , 0.6f , 0.2f , 1.f ) , " Fiber " ) ;
}
2019-02-28 18:31:45 +00:00
}
2021-10-10 12:12:13 +00:00
if ( ! data . message . empty ( ) )
{
TextFocused ( " Context: " , data . message . c_str ( ) ) ;
}
2020-09-30 14:32:34 +00:00
if ( data . callstack ! = 0 )
{
if ( ImGui : : TreeNode ( " Call stack " ) )
{
ImGui : : BeginChild ( " ##callstackFailure " , ImVec2 ( 1200 , 500 ) ) ;
2020-12-08 01:03:23 +00:00
if ( ImGui : : BeginTable ( " ##callstack " , 4 , ImGuiTableFlags_Resizable | ImGuiTableFlags_Borders ) )
2020-09-30 14:32:34 +00:00
{
2021-01-21 21:57:59 +00:00
ImGui : : TableSetupColumn ( " Frame " , ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize ) ;
2020-12-08 00:45:45 +00:00
ImGui : : TableSetupColumn ( " Function " ) ;
ImGui : : TableSetupColumn ( " Location " ) ;
ImGui : : TableSetupColumn ( " Image " ) ;
ImGui : : TableHeadersRow ( ) ;
auto & cs = s_instance - > m_worker . GetCallstack ( data . callstack ) ;
int fidx = 0 ;
int bidx = 0 ;
for ( auto & entry : cs )
2020-09-30 14:32:34 +00:00
{
2020-12-08 00:45:45 +00:00
auto frameData = s_instance - > m_worker . GetCallstackFrame ( entry ) ;
if ( ! frameData )
2020-09-30 14:32:34 +00:00
{
2020-12-08 00:45:45 +00:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : Text ( " %i " , fidx + + ) ;
ImGui : : TableNextColumn ( ) ;
char buf [ 32 ] ;
sprintf ( buf , " %p " , ( void * ) s_instance - > m_worker . GetCanonicalPointer ( entry ) ) ;
ImGui : : TextUnformatted ( buf ) ;
if ( ImGui : : IsItemHovered ( ) )
{
ImGui : : BeginTooltip ( ) ;
ImGui : : TextUnformatted ( " Click on entry to copy it to clipboard. " ) ;
ImGui : : EndTooltip ( ) ;
if ( ImGui : : IsItemClicked ( ) )
{
ImGui : : SetClipboardText ( buf ) ;
}
}
2020-09-30 14:32:34 +00:00
}
2020-12-08 00:45:45 +00:00
else
2020-09-30 14:32:34 +00:00
{
2020-12-08 00:45:45 +00:00
const auto fsz = frameData - > size ;
for ( uint8_t f = 0 ; f < fsz ; f + + )
2020-09-30 14:32:34 +00:00
{
2020-12-08 00:45:45 +00:00
const auto & frame = frameData - > data [ f ] ;
auto txt = s_instance - > m_worker . GetString ( frame . name ) ;
if ( fidx = = 0 & & f ! = fsz - 1 )
2020-09-30 14:32:34 +00:00
{
2020-12-08 00:45:45 +00:00
auto test = s_tracyStackFrames ;
bool match = false ;
do
2020-09-30 14:32:34 +00:00
{
2020-12-08 00:45:45 +00:00
if ( strcmp ( txt , * test ) = = 0 )
{
match = true ;
break ;
}
2020-09-30 14:32:34 +00:00
}
2020-12-08 00:45:45 +00:00
while ( * + + test ) ;
if ( match ) continue ;
2020-09-30 14:32:34 +00:00
}
2020-12-08 00:45:45 +00:00
bidx + + ;
2020-09-30 14:32:34 +00:00
2020-12-08 00:45:45 +00:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
if ( f = = fsz - 1 )
{
ImGui : : Text ( " %i " , fidx + + ) ;
}
else
{
TextDisabledUnformatted ( " inline " ) ;
}
ImGui : : TableNextColumn ( ) ;
{
ImGui : : PushTextWrapPos ( 0.0f ) ;
if ( txt [ 0 ] = = ' [ ' )
{
TextDisabledUnformatted ( txt ) ;
}
else
{
ImGui : : TextUnformatted ( txt ) ;
}
ImGui : : PopTextWrapPos ( ) ;
}
if ( ImGui : : IsItemHovered ( ) )
{
ImGui : : BeginTooltip ( ) ;
ImGui : : TextUnformatted ( " Click on entry to copy it to clipboard. " ) ;
ImGui : : EndTooltip ( ) ;
if ( ImGui : : IsItemClicked ( ) )
{
ImGui : : SetClipboardText ( txt ) ;
}
}
ImGui : : TableNextColumn ( ) ;
2020-09-30 14:32:34 +00:00
ImGui : : PushTextWrapPos ( 0.0f ) ;
2020-12-08 00:45:45 +00:00
txt = s_instance - > m_worker . GetString ( frame . file ) ;
2021-06-19 10:47:55 +00:00
TextDisabledUnformatted ( LocationToString ( txt , frame . line ) ) ;
2020-12-08 00:45:45 +00:00
if ( ImGui : : IsItemHovered ( ) )
{
ImGui : : BeginTooltip ( ) ;
ImGui : : TextUnformatted ( " Click on entry to copy it to clipboard. " ) ;
ImGui : : EndTooltip ( ) ;
if ( ImGui : : IsItemClicked ( ) )
{
ImGui : : SetClipboardText ( txt ) ;
}
2020-09-30 14:32:34 +00:00
}
ImGui : : PopTextWrapPos ( ) ;
2020-12-08 00:45:45 +00:00
ImGui : : TableNextColumn ( ) ;
if ( frameData - > imageName . Active ( ) )
{
TextDisabledUnformatted ( s_instance - > m_worker . GetString ( frameData - > imageName ) ) ;
}
2020-09-30 14:32:34 +00:00
}
}
}
2020-12-08 00:45:45 +00:00
ImGui : : EndTable ( ) ;
2020-09-30 14:32:34 +00:00
}
ImGui : : EndChild ( ) ;
ImGui : : TreePop ( ) ;
}
}
2019-01-14 22:42:58 +00:00
ImGui : : Separator ( ) ;
if ( ImGui : : Button ( " I understand " ) )
{
ImGui : : CloseCurrentPopup ( ) ;
s_instance - > m_worker . ClearFailure ( ) ;
}
ImGui : : EndPopup ( ) ;
}
2021-05-15 12:25:45 +00:00
bool saveFailed = false ;
if ( ! s_instance - > m_filenameStaging . empty ( ) )
{
ImGui : : OpenPopup ( " Save trace " ) ;
}
if ( ImGui : : BeginPopupModal ( " Save trace " , nullptr , ImGuiWindowFlags_AlwaysAutoResize ) )
{
assert ( ! s_instance - > m_filenameStaging . empty ( ) ) ;
auto fn = s_instance - > m_filenameStaging . c_str ( ) ;
2022-05-01 11:04:16 +00:00
ImGui : : PushFont ( s_instance - > m_bigFont ) ;
2021-05-15 12:25:45 +00:00
TextFocused ( " Path: " , fn ) ;
2022-05-01 11:04:16 +00:00
ImGui : : PopFont ( ) ;
2021-05-15 12:25:45 +00:00
ImGui : : Separator ( ) ;
static FileWrite : : Compression comp = FileWrite : : Compression : : Fast ;
static int zlvl = 6 ;
2022-08-17 10:07:38 +00:00
ImGui : : TextUnformatted ( ICON_FA_FILE_ZIPPER " Trace compression " ) ;
2021-05-15 12:25:45 +00:00
ImGui : : SameLine ( ) ;
TextDisabledUnformatted ( " Can be changed later with the upgrade utility " ) ;
ImGui : : Indent ( ) ;
int idx = 0 ;
while ( CompressionName [ idx ] )
{
if ( ImGui : : RadioButton ( CompressionName [ idx ] , ( int ) comp = = idx ) ) comp = ( FileWrite : : Compression ) idx ;
ImGui : : SameLine ( ) ;
2021-06-04 13:29:08 +00:00
TextDisabledUnformatted ( CompressionDesc [ idx ] ) ;
2021-05-15 12:25:45 +00:00
idx + + ;
}
ImGui : : Unindent ( ) ;
ImGui : : TextUnformatted ( " Zstd level " ) ;
ImGui : : SameLine ( ) ;
TextDisabledUnformatted ( " Increasing level decreases file size, but increases save and load times " ) ;
ImGui : : Indent ( ) ;
2021-06-19 22:25:30 +00:00
if ( ImGui : : SliderInt ( " ##zstd " , & zlvl , 1 , 22 , " %d " , ImGuiSliderFlags_AlwaysClamp ) )
{
comp = FileWrite : : Compression : : Zstd ;
}
2021-05-15 12:25:45 +00:00
ImGui : : Unindent ( ) ;
2021-05-15 13:50:20 +00:00
static bool buildDict = false ;
2021-05-15 13:52:54 +00:00
if ( s_instance - > m_worker . GetFrameImageCount ( ) ! = 0 )
{
ImGui : : Separator ( ) ;
ImGui : : Checkbox ( " Build frame images dictionary " , & buildDict ) ;
ImGui : : SameLine ( ) ;
TextDisabledUnformatted ( " Decreases run-time memory requirements " ) ;
}
2021-05-15 13:50:20 +00:00
2021-05-15 12:25:45 +00:00
ImGui : : Separator ( ) ;
2022-08-17 10:07:38 +00:00
if ( ImGui : : Button ( ICON_FA_FLOPPY_DISK " Save trace " ) )
2021-05-15 12:25:45 +00:00
{
2021-05-15 13:50:20 +00:00
saveFailed = ! s_instance - > Save ( fn , comp , zlvl , buildDict ) ;
2021-05-15 12:25:45 +00:00
s_instance - > m_filenameStaging . clear ( ) ;
ImGui : : CloseCurrentPopup ( ) ;
}
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( " Cancel " ) )
{
s_instance - > m_filenameStaging . clear ( ) ;
ImGui : : CloseCurrentPopup ( ) ;
}
ImGui : : EndPopup ( ) ;
}
if ( saveFailed ) ImGui : : OpenPopup ( " Save failed " ) ;
if ( ImGui : : BeginPopupModal ( " Save failed " , nullptr , ImGuiWindowFlags_AlwaysAutoResize ) )
{
2022-04-25 21:29:44 +00:00
ImGui : : PushFont ( s_instance - > m_bigFont ) ;
2022-08-17 10:07:38 +00:00
TextCentered ( ICON_FA_TRIANGLE_EXCLAMATION ) ;
2022-04-25 21:29:44 +00:00
ImGui : : PopFont ( ) ;
2021-05-15 12:25:45 +00:00
ImGui : : TextUnformatted ( " Could not save trace at the specified location. Try again somewhere else. " ) ;
ImGui : : Separator ( ) ;
if ( ImGui : : Button ( " Oh well " ) ) ImGui : : CloseCurrentPopup ( ) ;
ImGui : : EndPopup ( ) ;
}
2019-03-06 23:57:25 +00:00
s_time + = ImGui : : GetIO ( ) . DeltaTime ;
2018-04-29 23:16:08 +00:00
return s_instance - > DrawImpl ( ) ;
2017-09-15 00:30:22 +00:00
}
2018-04-21 20:42:32 +00:00
static const char * MainWindowButtons [ ] = {
2018-08-17 21:24:25 +00:00
ICON_FA_PLAY " Resume " ,
2018-11-25 18:15:16 +00:00
ICON_FA_PAUSE " Pause " ,
ICON_FA_SQUARE " Stopped "
2018-04-21 20:42:32 +00:00
} ;
enum { MainWindowButtonsCount = sizeof ( MainWindowButtons ) / sizeof ( * MainWindowButtons ) } ;
2018-04-29 23:16:08 +00:00
bool View : : DrawImpl ( )
2017-09-15 00:30:22 +00:00
{
2018-02-13 13:57:47 +00:00
if ( ! m_worker . HasData ( ) )
2017-09-20 18:38:12 +00:00
{
2020-09-06 11:54:22 +00:00
bool keepOpen = true ;
2018-07-10 18:47:09 +00:00
char tmp [ 2048 ] ;
sprintf ( tmp , " %s###Connection " , m_worker . GetAddr ( ) . c_str ( ) ) ;
2021-04-09 15:43:48 +00:00
ImGui : : Begin ( tmp , & keepOpen , ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse ) ;
2022-04-25 21:29:44 +00:00
ImGui : : PushFont ( m_bigFont ) ;
2018-08-17 21:56:06 +00:00
TextCentered ( ICON_FA_WIFI ) ;
2022-04-25 21:29:44 +00:00
ImGui : : PopFont ( ) ;
2019-02-10 01:50:34 +00:00
ImGui : : TextUnformatted ( " Waiting for connection... " ) ;
2019-03-07 16:00:40 +00:00
DrawWaitingDots ( s_time ) ;
2017-09-20 18:38:12 +00:00
ImGui : : End ( ) ;
2020-09-06 11:54:22 +00:00
return keepOpen ;
2017-09-30 14:58:02 +00:00
}
2017-09-30 12:37:21 +00:00
2020-05-06 22:53:31 +00:00
if ( ! m_uarchSet )
{
m_uarchSet = true ;
m_sourceView - > SetCpuId ( m_worker . GetCpuId ( ) ) ;
}
2019-07-26 21:05:24 +00:00
if ( ! m_userData . Valid ( ) ) m_userData . Init ( m_worker . GetCaptureProgram ( ) . c_str ( ) , m_worker . GetCaptureTime ( ) ) ;
2020-02-08 12:07:02 +00:00
if ( m_saveThreadState . load ( std : : memory_order_acquire ) = = SaveThreadState : : NeedsJoin )
2019-05-28 17:56:18 +00:00
{
m_saveThread . join ( ) ;
2020-02-08 12:07:02 +00:00
m_saveThreadState . store ( SaveThreadState : : Inert , std : : memory_order_release ) ;
const auto src = m_srcFileBytes . load ( std : : memory_order_relaxed ) ;
const auto dst = m_dstFileBytes . load ( std : : memory_order_relaxed ) ;
m_notificationTime = 4 ;
char buf [ 1024 ] ;
sprintf ( buf , " Trace size %s (%.2f%% ratio) " , MemSizeToString ( dst ) , 100.f * dst / src ) ;
m_notificationText = buf ;
2019-05-28 17:56:18 +00:00
}
2018-12-22 16:36:20 +00:00
const auto & io = ImGui : : GetIO ( ) ;
assert ( m_shortcut = = ShortcutAction : : None ) ;
if ( io . KeyCtrl )
{
2022-04-26 23:16:46 +00:00
if ( ImGui : : IsKeyPressed ( ImGuiKey_F ) )
2018-12-22 16:36:20 +00:00
{
2018-12-22 16:39:22 +00:00
m_findZone . show = true ;
2018-12-22 16:36:20 +00:00
m_shortcut = ShortcutAction : : OpenFind ;
}
}
2018-08-04 17:47:09 +00:00
if ( ! m_frames ) m_frames = m_worker . GetFramesBase ( ) ;
2018-03-24 22:43:51 +00:00
const auto th = ImGui : : GetTextLineHeight ( ) ;
2018-04-21 20:42:32 +00:00
float bw = 0 ;
for ( int i = 0 ; i < MainWindowButtonsCount ; i + + )
{
bw = std : : max ( bw , ImGui : : CalcTextSize ( MainWindowButtons [ i ] ) . x ) ;
}
bw + = th ;
2018-03-24 22:43:51 +00:00
2018-04-29 23:16:08 +00:00
bool keepOpen = true ;
bool * keepOpenPtr = nullptr ;
2019-06-22 12:04:48 +00:00
( void ) keepOpenPtr ;
2019-08-04 10:58:20 +00:00
if ( m_staticView )
2018-04-29 23:16:08 +00:00
{
keepOpenPtr = & keepOpen ;
}
2020-03-26 22:08:29 +00:00
# ifndef TRACY_NO_ROOT_WINDOW
2018-08-17 15:24:18 +00:00
if ( ! m_titleSet & & m_stcb )
{
m_titleSet = true ;
m_stcb ( m_worker . GetCaptureName ( ) . c_str ( ) ) ;
}
2020-05-07 13:27:11 +00:00
ImGuiViewport * viewport = ImGui : : GetMainViewport ( ) ;
2020-05-03 11:27:58 +00:00
{
auto & style = ImGui : : GetStyle ( ) ;
const auto wrPrev = style . WindowRounding ;
const auto wbsPrev = style . WindowBorderSize ;
const auto wpPrev = style . WindowPadding ;
style . WindowRounding = 0.f ;
style . WindowBorderSize = 0.f ;
style . WindowPadding = ImVec2 ( 4.f , 4.f ) ;
style . Colors [ ImGuiCol_WindowBg ] = ImVec4 ( 0.129f , 0.137f , 0.11f , 1.f ) ;
2020-05-07 13:27:11 +00:00
ImGui : : SetNextWindowPos ( viewport - > Pos ) ;
2020-05-03 11:27:58 +00:00
ImGui : : SetNextWindowSize ( ImVec2 ( m_rootWidth , m_rootHeight ) ) ;
2020-05-07 13:27:11 +00:00
ImGui : : SetNextWindowViewport ( viewport - > ID ) ;
2022-04-22 20:38:05 +00:00
ImGui : : Begin ( " Timeline view###Profiler " , nullptr , ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoNavFocus ) ;
2020-05-03 11:27:58 +00:00
style . WindowRounding = wrPrev ;
style . WindowBorderSize = wbsPrev ;
style . WindowPadding = wpPrev ;
style . Colors [ ImGuiCol_WindowBg ] = ImVec4 ( 0.11f , 0.11f , 0.08f , 1.f ) ;
}
2018-08-17 15:00:56 +00:00
# else
2018-08-17 15:24:18 +00:00
char tmp [ 2048 ] ;
sprintf ( tmp , " %s###Profiler " , m_worker . GetCaptureName ( ) . c_str ( ) ) ;
ImGui : : SetNextWindowSize ( ImVec2 ( 1550 , 800 ) , ImGuiCond_FirstUseEver ) ;
2018-07-26 21:38:45 +00:00
ImGui : : Begin ( tmp , keepOpenPtr , ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoBringToFrontOnFocus ) ;
2018-08-17 15:00:56 +00:00
# endif
2019-08-04 13:55:42 +00:00
if ( ! m_staticView )
{
2020-04-25 11:14:27 +00:00
if ( ImGui : : Button ( ICON_FA_WIFI ) | | m_forceConnectionPopup )
2019-08-04 13:55:42 +00:00
{
2020-04-25 11:14:27 +00:00
if ( m_forceConnectionPopup )
{
2020-05-07 23:49:15 +00:00
m_forceConnectionPopup . Decay ( false ) ;
2020-05-07 13:27:11 +00:00
ImGui : : SetNextWindowPos ( viewport - > Pos + ImGui : : GetCursorPos ( ) ) ;
2020-04-25 11:14:27 +00:00
}
2019-08-04 13:55:42 +00:00
ImGui : : OpenPopup ( " TracyConnectionPopup " ) ;
}
ImGui : : SameLine ( ) ;
if ( ImGui : : BeginPopup ( " TracyConnectionPopup " ) )
{
const bool wasDisconnectIssued = m_disconnectIssued ;
const bool discardData = ! DrawConnection ( ) ;
const bool disconnectIssuedJustNow = m_disconnectIssued ! = wasDisconnectIssued ;
if ( discardData ) keepOpen = false ;
if ( disconnectIssuedJustNow | | discardData ) ImGui : : CloseCurrentPopup ( ) ;
ImGui : : EndPopup ( ) ;
}
}
2021-02-07 17:11:24 +00:00
std : : lock_guard < std : : mutex > lock ( m_worker . GetDataLock ( ) ) ;
2021-02-07 17:29:29 +00:00
m_worker . DoPostponedWork ( ) ;
2018-03-24 13:45:01 +00:00
if ( ! m_worker . IsDataStatic ( ) )
{
2018-11-25 18:15:16 +00:00
if ( m_worker . IsConnected ( ) )
{
2020-09-12 13:49:41 +00:00
if ( ImGui : : Button ( m_viewMode = = ViewMode : : Paused ? MainWindowButtons [ 0 ] : MainWindowButtons [ 1 ] , ImVec2 ( bw , 0 ) ) )
{
if ( m_viewMode ! = ViewMode : : Paused )
{
m_viewMode = ViewMode : : Paused ;
2020-10-06 16:46:36 +00:00
m_viewModeHeuristicTry = false ;
2020-09-12 13:49:41 +00:00
}
else
{
ImGui : : OpenPopup ( " viewMode " ) ;
}
}
2018-11-25 18:15:16 +00:00
}
else
{
2021-08-20 22:52:30 +00:00
ImGui : : BeginDisabled ( ) ;
ImGui : : ButtonEx ( MainWindowButtons [ 2 ] , ImVec2 ( bw , 0 ) ) ;
ImGui : : EndDisabled ( ) ;
2018-11-25 18:15:16 +00:00
}
2020-09-12 13:49:41 +00:00
if ( ImGui : : BeginPopup ( " viewMode " ) )
{
2022-08-17 10:07:38 +00:00
if ( ImGui : : Selectable ( ICON_FA_MAGNIFYING_GLASS_PLUS " Newest three frames " ) )
2020-09-12 13:49:41 +00:00
{
m_viewMode = ViewMode : : LastFrames ;
}
if ( ImGui : : Selectable ( ICON_FA_RULER_HORIZONTAL " Use current zoom level " ) )
{
m_viewMode = ViewMode : : LastRange ;
}
ImGui : : EndPopup ( ) ;
}
2020-10-06 16:46:36 +00:00
else if ( m_viewModeHeuristicTry )
{
const auto lastTime = m_worker . GetLastTime ( ) ;
if ( lastTime > 5 * 1000 * 1000 * 1000ll )
{
if ( m_viewMode = = ViewMode : : LastFrames & & m_worker . GetFrameCount ( * m_worker . GetFramesBase ( ) ) < = 2 )
{
m_viewMode = ViewMode : : LastRange ;
ZoomToRange ( lastTime - 5 * 1000 * 1000 * 1000ll , lastTime , false ) ;
}
else
{
m_viewModeHeuristicTry = false ;
}
}
}
2018-03-24 13:45:01 +00:00
}
2018-08-17 14:34:58 +00:00
else
{
ImGui : : PushStyleColor ( ImGuiCol_Button , ( ImVec4 ) ImColor : : HSV ( 0.f , 0.6f , 0.6f ) ) ;
ImGui : : PushStyleColor ( ImGuiCol_ButtonHovered , ( ImVec4 ) ImColor : : HSV ( 0.f , 0.7f , 0.7f ) ) ;
ImGui : : PushStyleColor ( ImGuiCol_ButtonActive , ( ImVec4 ) ImColor : : HSV ( 0.f , 0.8f , 0.8f ) ) ;
2018-08-17 21:22:13 +00:00
if ( ImGui : : Button ( ICON_FA_POWER_OFF ) ) keepOpen = false ;
2018-08-17 14:34:58 +00:00
ImGui : : PopStyleColor ( 3 ) ;
}
ImGui : : SameLine ( ) ;
2022-08-17 10:07:38 +00:00
ToggleButton ( ICON_FA_GEAR " Options " , m_showOptions ) ;
2017-09-30 12:37:21 +00:00
ImGui : : SameLine ( ) ;
2018-12-18 15:13:11 +00:00
ToggleButton ( ICON_FA_TAGS " Messages " , m_showMessages ) ;
2017-10-14 12:36:30 +00:00
ImGui : : SameLine ( ) ;
2022-08-17 10:07:38 +00:00
ToggleButton ( ICON_FA_MAGNIFYING_GLASS " Find zone " , m_findZone . show ) ;
2018-03-24 13:40:48 +00:00
ImGui : : SameLine ( ) ;
2022-08-17 10:07:38 +00:00
ToggleButton ( ICON_FA_ARROW_UP_WIDE_SHORT " Statistics " , m_showStatistics ) ;
2018-01-17 11:49:50 +00:00
ImGui : : SameLine ( ) ;
2018-12-18 15:13:11 +00:00
ToggleButton ( ICON_FA_MEMORY " Memory " , m_memInfo . show ) ;
2018-04-01 18:34:21 +00:00
ImGui : : SameLine ( ) ;
2022-08-17 10:07:38 +00:00
ToggleButton ( ICON_FA_SCALE_BALANCED " Compare " , m_compare . show ) ;
2018-04-21 22:52:33 +00:00
ImGui : : SameLine ( ) ;
2018-12-18 15:13:11 +00:00
ToggleButton ( ICON_FA_FINGERPRINT " Info " , m_showInfo ) ;
2018-08-08 17:25:13 +00:00
ImGui : : SameLine ( ) ;
2022-08-17 10:07:38 +00:00
if ( ImGui : : Button ( ICON_FA_SCREWDRIVER_WRENCH ) ) ImGui : : OpenPopup ( " ToolsPopup " ) ;
2019-10-14 18:07:55 +00:00
if ( ImGui : : BeginPopup ( " ToolsPopup " ) )
{
const auto ficnt = m_worker . GetFrameImageCount ( ) ;
if ( ButtonDisablable ( ICON_FA_PLAY " Playback " , ficnt = = 0 ) )
{
m_showPlayback = true ;
}
const auto & ctd = m_worker . GetCpuThreadData ( ) ;
2022-08-17 10:07:38 +00:00
if ( ButtonDisablable ( ICON_FA_SLIDERS " CPU data " , ctd . empty ( ) ) )
2019-10-14 18:07:55 +00:00
{
m_showCpuDataWindow = true ;
}
2022-08-17 10:07:38 +00:00
ToggleButton ( ICON_FA_NOTE_STICKY " Annotations " , m_showAnnotationList ) ;
2020-08-03 14:07:28 +00:00
ToggleButton ( ICON_FA_RULER " Limits " , m_showRanges ) ;
2021-11-13 14:58:25 +00:00
const auto cscnt = m_worker . GetContextSwitchSampleCount ( ) ;
if ( ButtonDisablable ( ICON_FA_HOURGLASS_HALF " Wait stacks " , cscnt = = 0 ) )
{
m_showWaitStacks = true ;
}
2019-10-14 18:07:55 +00:00
ImGui : : EndPopup ( ) ;
}
2021-11-18 21:48:32 +00:00
if ( m_sscb )
{
ImGui : : SameLine ( ) ;
2022-08-17 10:07:38 +00:00
if ( ImGui : : Button ( ICON_FA_MAGNIFYING_GLASS_PLUS ) ) ImGui : : OpenPopup ( " ZoomPopup " ) ;
2021-11-18 21:48:32 +00:00
if ( ImGui : : BeginPopup ( " ZoomPopup " ) )
{
if ( ImGui : : Button ( " 50% " ) ) m_sscb ( 1.f / 2 , m_fixedFont , m_bigFont , m_smallFont ) ;
if ( ImGui : : Button ( " 57% " ) ) m_sscb ( 1.f / 1.75f , m_fixedFont , m_bigFont , m_smallFont ) ;
if ( ImGui : : Button ( " 66% " ) ) m_sscb ( 1.f / 1.5f , m_fixedFont , m_bigFont , m_smallFont ) ;
if ( ImGui : : Button ( " 80% " ) ) m_sscb ( 1.f / 1.25f , m_fixedFont , m_bigFont , m_smallFont ) ;
if ( ImGui : : Button ( " 100% " ) ) m_sscb ( 1.f , m_fixedFont , m_bigFont , m_smallFont ) ;
if ( ImGui : : Button ( " 125% " ) ) m_sscb ( 1.25f , m_fixedFont , m_bigFont , m_smallFont ) ;
if ( ImGui : : Button ( " 150% " ) ) m_sscb ( 1.5f , m_fixedFont , m_bigFont , m_smallFont ) ;
if ( ImGui : : Button ( " 175% " ) ) m_sscb ( 1.75f , m_fixedFont , m_bigFont , m_smallFont ) ;
if ( ImGui : : Button ( " 200% " ) ) m_sscb ( 2.f , m_fixedFont , m_bigFont , m_smallFont ) ;
if ( ImGui : : Button ( " 225% " ) ) m_sscb ( 2.25f , m_fixedFont , m_bigFont , m_smallFont ) ;
if ( ImGui : : Button ( " 250% " ) ) m_sscb ( 2.5f , m_fixedFont , m_bigFont , m_smallFont ) ;
if ( ImGui : : Button ( " 275% " ) ) m_sscb ( 2.75f , m_fixedFont , m_bigFont , m_smallFont ) ;
if ( ImGui : : Button ( " 300% " ) ) m_sscb ( 3.f , m_fixedFont , m_bigFont , m_smallFont ) ;
ImGui : : EndPopup ( ) ;
}
}
2019-10-14 18:07:55 +00:00
ImGui : : SameLine ( ) ;
2019-02-27 01:26:43 +00:00
if ( ImGui : : SmallButton ( " " ICON_FA_CARET_LEFT " " ) ) ZoomToPrevFrame ( ) ;
2018-08-08 16:40:31 +00:00
ImGui : : SameLine ( ) ;
{
2022-08-20 15:02:29 +00:00
const auto vis = m_tc . Vis ( m_frames ) . visible ;
2018-08-08 16:40:31 +00:00
if ( ! vis )
{
ImGui : : PushStyleColor ( ImGuiCol_Text , GImGui - > Style . Colors [ ImGuiCol_TextDisabled ] ) ;
}
2022-07-30 17:32:25 +00:00
ImGui : : Text ( " %s: %s " , GetFrameSetName ( * m_frames ) , RealToString ( m_worker . GetFrameCount ( * m_frames ) ) ) ;
2018-08-08 16:40:31 +00:00
if ( ! vis )
{
ImGui : : PopStyleColor ( ) ;
}
2020-07-11 22:18:44 +00:00
if ( ImGui : : IsItemClicked ( ) ) ImGui : : OpenPopup ( " GoToFramePopup " ) ;
2018-08-08 16:40:31 +00:00
}
ImGui : : SameLine ( ) ;
2019-02-27 01:26:43 +00:00
if ( ImGui : : SmallButton ( " " ICON_FA_CARET_RIGHT " " ) ) ZoomToNextFrame ( ) ;
2018-08-08 16:40:31 +00:00
ImGui : : SameLine ( ) ;
2018-08-04 19:43:29 +00:00
if ( ImGui : : BeginCombo ( " ##frameCombo " , nullptr , ImGuiComboFlags_NoPreview ) )
{
auto & frames = m_worker . GetFrames ( ) ;
for ( auto & fd : frames )
{
bool isSelected = m_frames = = fd ;
2022-07-30 17:32:25 +00:00
if ( ImGui : : Selectable ( GetFrameSetName ( * fd ) , isSelected ) )
2018-08-04 19:43:29 +00:00
{
m_frames = fd ;
}
if ( isSelected )
{
ImGui : : SetItemDefaultFocus ( ) ;
}
2019-02-22 20:04:41 +00:00
ImGui : : SameLine ( ) ;
2020-01-31 00:43:24 +00:00
ImGui : : TextDisabled ( " (%s) " , RealToString ( fd - > frames . size ( ) ) ) ;
2018-08-04 19:43:29 +00:00
}
ImGui : : EndCombo ( ) ;
}
2020-05-03 11:54:37 +00:00
if ( ImGui : : BeginPopup ( " GoToFramePopup " ) )
{
static int frameNum = 1 ;
const bool mainFrameSet = m_frames - > name = = 0 ;
const auto numFrames = mainFrameSet ? m_frames - > frames . size ( ) - 1 : m_frames - > frames . size ( ) ;
const auto frameOffset = mainFrameSet ? 0 : 1 ;
2021-11-18 19:33:44 +00:00
ImGui : : SetNextItemWidth ( 120 * GetScale ( ) ) ;
2021-11-13 14:13:35 +00:00
const bool clicked = ImGui : : InputInt ( " ##goToFrame " , & frameNum , 1 , 100 , ImGuiInputTextFlags_EnterReturnsTrue ) ;
2020-05-03 11:54:37 +00:00
frameNum = std : : min ( std : : max ( frameNum , 1 ) , int ( numFrames ) ) ;
2021-11-13 14:13:35 +00:00
if ( clicked ) ZoomToRange ( m_worker . GetFrameBegin ( * m_frames , frameNum - frameOffset ) , m_worker . GetFrameEnd ( * m_frames , frameNum - frameOffset ) ) ;
2020-05-03 11:54:37 +00:00
ImGui : : EndPopup ( ) ;
}
2020-04-13 13:00:37 +00:00
2020-04-13 12:41:05 +00:00
{
2020-04-13 13:00:37 +00:00
ImGui : : SameLine ( ) ;
ImGui : : Spacing ( ) ;
ImGui : : SameLine ( ) ;
const auto targetLabelSize = ImGui : : CalcTextSize ( " WWWWWWW " ) . x ;
auto cx = ImGui : : GetCursorPosX ( ) ;
ImGui : : Text ( ICON_FA_EYE " %s " , TimeToString ( m_vd . zvEnd - m_vd . zvStart ) ) ;
2022-01-01 15:57:48 +00:00
TooltipIfHovered ( " View span " ) ;
2020-04-13 13:00:37 +00:00
ImGui : : SameLine ( ) ;
auto dx = ImGui : : GetCursorPosX ( ) - cx ;
if ( dx < targetLabelSize ) ImGui : : SameLine ( cx + targetLabelSize ) ;
cx = ImGui : : GetCursorPosX ( ) ;
ImGui : : Text ( ICON_FA_DATABASE " %s " , TimeToString ( m_worker . GetLastTime ( ) ) ) ;
if ( ImGui : : IsItemHovered ( ) )
{
ImGui : : BeginTooltip ( ) ;
ImGui : : Text ( " Time span " ) ;
ImGui : : EndTooltip ( ) ;
2020-07-11 12:11:13 +00:00
if ( ImGui : : IsItemClicked ( 2 ) )
{
ZoomToRange ( 0 , m_worker . GetLastTime ( ) ) ;
}
2020-04-13 13:00:37 +00:00
}
ImGui : : SameLine ( ) ;
dx = ImGui : : GetCursorPosX ( ) - cx ;
if ( dx < targetLabelSize ) ImGui : : SameLine ( cx + targetLabelSize ) ;
cx = ImGui : : GetCursorPosX ( ) ;
ImGui : : Text ( ICON_FA_MEMORY " %s " , MemSizeToString ( memUsage ) ) ;
2022-01-01 15:57:48 +00:00
TooltipIfHovered ( " Profiler memory usage " ) ;
2020-11-13 16:22:10 +00:00
if ( m_totalMemory ! = 0 )
{
ImGui : : SameLine ( ) ;
const auto memUse = float ( memUsage ) / m_totalMemory * 100 ;
if ( memUse < 80 )
{
ImGui : : TextDisabled ( " (%.2f%%) " , memUse ) ;
}
else
{
ImGui : : TextColored ( ImVec4 ( 1.f , 0.25f , 0.25f , 1.f ) , " (%.2f%%) " , memUse ) ;
}
}
2020-04-13 13:00:37 +00:00
ImGui : : SameLine ( ) ;
dx = ImGui : : GetCursorPosX ( ) - cx ;
if ( dx < targetLabelSize ) ImGui : : SameLine ( cx + targetLabelSize ) ;
ImGui : : Spacing ( ) ;
2020-04-13 12:41:05 +00:00
}
2019-08-28 18:27:39 +00:00
DrawNotificationArea ( ) ;
2019-06-02 13:00:50 +00:00
2019-08-28 18:27:39 +00:00
m_frameHover = - 1 ;
2019-03-27 20:39:53 +00:00
DrawFrames ( ) ;
2020-05-03 11:23:26 +00:00
const auto dockspaceId = ImGui : : GetID ( " tracyDockspace " ) ;
2019-03-16 20:11:18 +00:00
ImGui : : DockSpace ( dockspaceId , ImVec2 ( 0 , 0 ) , ImGuiDockNodeFlags_NoDockingInCentralNode ) ;
2020-05-03 11:29:51 +00:00
if ( ImGuiDockNode * node = ImGui : : DockBuilderGetCentralNode ( dockspaceId ) )
{
node - > LocalFlags | = ImGuiDockNodeFlags_NoTabBar ;
}
2020-05-03 11:23:26 +00:00
ImGui : : SetNextWindowDockID ( dockspaceId ) ;
2020-05-03 11:27:58 +00:00
{
auto & style = ImGui : : GetStyle ( ) ;
const auto wpPrev = style . WindowPadding ;
style . WindowPadding = ImVec2 ( 1 , 0 ) ;
# ifndef TRACY_NO_ROOT_WINDOW
style . Colors [ ImGuiCol_WindowBg ] = ImVec4 ( 0.129f , 0.137f , 0.11f , 1.f ) ;
# endif
2020-06-05 17:23:27 +00:00
ImGui : : Begin ( " Work area " , nullptr , ImGuiWindowFlags_NoNavFocus ) ;
2020-05-03 11:27:58 +00:00
style . WindowPadding = wpPrev ;
# ifndef TRACY_NO_ROOT_WINDOW
style . Colors [ ImGuiCol_WindowBg ] = ImVec4 ( 0.11f , 0.11f , 0.08f , 1.f ) ;
# endif
}
2020-05-03 11:23:26 +00:00
2022-07-02 13:38:10 +00:00
DrawTimeline ( ) ;
2019-08-28 18:27:39 +00:00
2020-05-03 11:23:26 +00:00
ImGui : : End ( ) ;
2019-08-28 18:27:39 +00:00
ImGui : : End ( ) ;
m_zoneHighlight = nullptr ;
m_gpuHighlight = nullptr ;
DrawInfoWindow ( ) ;
if ( m_showOptions ) DrawOptions ( ) ;
if ( m_showMessages ) DrawMessages ( ) ;
if ( m_findZone . show ) DrawFindZone ( ) ;
if ( m_showStatistics ) DrawStatistics ( ) ;
if ( m_memInfo . show ) DrawMemory ( ) ;
if ( m_memInfo . showAllocList ) DrawAllocList ( ) ;
if ( m_compare . show ) DrawCompare ( ) ;
if ( m_callstackInfoWindow ! = 0 ) DrawCallstackWindow ( ) ;
if ( m_memoryAllocInfoWindow > = 0 ) DrawMemoryAllocWindow ( ) ;
if ( m_showInfo ) DrawInfo ( ) ;
2020-03-22 19:53:59 +00:00
if ( m_sourceViewFile ) DrawTextEditor ( ) ;
2019-08-28 18:27:39 +00:00
if ( m_lockInfoWindow ! = InvalidId ) DrawLockInfoWindow ( ) ;
if ( m_showPlayback ) DrawPlayback ( ) ;
if ( m_showCpuDataWindow ) DrawCpuDataWindow ( ) ;
2019-10-13 13:50:37 +00:00
if ( m_selectedAnnotation ) DrawSelectedAnnotation ( ) ;
2019-10-14 18:37:24 +00:00
if ( m_showAnnotationList ) DrawAnnotationList ( ) ;
2020-02-29 17:15:59 +00:00
if ( m_sampleParents . symAddr ! = 0 ) DrawSampleParents ( ) ;
2020-07-31 14:37:47 +00:00
if ( m_showRanges ) DrawRanges ( ) ;
2021-11-13 14:58:25 +00:00
if ( m_showWaitStacks ) DrawWaitStacks ( ) ;
2019-08-28 18:27:39 +00:00
2020-07-31 15:50:12 +00:00
if ( m_setRangePopup . active )
{
m_setRangePopup . active = false ;
ImGui : : OpenPopup ( " SetZoneRange " ) ;
}
if ( ImGui : : BeginPopup ( " SetZoneRange " ) )
{
2020-08-06 22:24:22 +00:00
const auto s = std : : min ( m_setRangePopup . min , m_setRangePopup . max ) ;
const auto e = std : : max ( m_setRangePopup . min , m_setRangePopup . max ) ;
2022-08-17 10:07:38 +00:00
if ( ImGui : : Selectable ( ICON_FA_MAGNIFYING_GLASS " Limit find zone time range " ) )
2020-07-31 15:50:12 +00:00
{
m_findZone . range . active = true ;
2020-08-06 22:24:22 +00:00
m_findZone . range . min = s ;
m_findZone . range . max = e ;
2020-07-31 15:50:12 +00:00
}
2022-08-17 10:07:38 +00:00
if ( ImGui : : Selectable ( ICON_FA_ARROW_UP_WIDE_SHORT " Limit statistics time range " ) )
2020-08-04 12:31:53 +00:00
{
m_statRange . active = true ;
2020-08-06 22:24:22 +00:00
m_statRange . min = s ;
m_statRange . max = e ;
2020-08-04 12:31:53 +00:00
}
2021-11-29 18:34:43 +00:00
if ( ImGui : : Selectable ( ICON_FA_HOURGLASS_HALF " Limit wait stacks range " ) )
2021-11-13 17:43:55 +00:00
{
m_waitStackRange . active = true ;
m_waitStackRange . min = s ;
m_waitStackRange . max = e ;
}
2021-11-29 17:17:19 +00:00
if ( ImGui : : Selectable ( ICON_FA_MEMORY " Limit memory range " ) )
{
m_memInfo . range . active = true ;
m_memInfo . range . min = s ;
m_memInfo . range . max = e ;
}
ImGui : : Separator ( ) ;
2022-08-17 10:07:38 +00:00
if ( ImGui : : Selectable ( ICON_FA_NOTE_STICKY " Add annotation " ) )
2020-08-04 14:40:35 +00:00
{
2022-03-15 16:25:28 +00:00
AddAnnotation ( s , e ) ;
2020-08-04 14:40:35 +00:00
}
2020-07-31 15:50:12 +00:00
ImGui : : EndPopup ( ) ;
}
2020-08-04 14:49:39 +00:00
m_setRangePopupOpen = ImGui : : IsPopupOpen ( " SetZoneRange " ) ;
2020-07-31 15:50:12 +00:00
2019-08-28 18:27:39 +00:00
if ( m_zoomAnim . active )
{
2020-09-12 13:49:41 +00:00
if ( m_viewMode = = ViewMode : : LastRange )
{
const auto delta = m_worker . GetLastTime ( ) - m_vd . zvEnd ;
if ( delta ! = 0 )
{
m_zoomAnim . start0 + = delta ;
m_zoomAnim . start1 + = delta ;
m_zoomAnim . end0 + = delta ;
m_zoomAnim . end1 + = delta ;
}
}
2019-08-28 18:27:39 +00:00
m_zoomAnim . progress + = io . DeltaTime * 3.33f ;
if ( m_zoomAnim . progress > = 1.f )
{
m_zoomAnim . active = false ;
m_vd . zvStart = m_zoomAnim . start1 ;
m_vd . zvEnd = m_zoomAnim . end1 ;
}
else
{
const auto v = sqrt ( sin ( M_PI_2 * m_zoomAnim . progress ) ) ;
m_vd . zvStart = int64_t ( m_zoomAnim . start0 + ( m_zoomAnim . start1 - m_zoomAnim . start0 ) * v ) ;
m_vd . zvEnd = int64_t ( m_zoomAnim . end0 + ( m_zoomAnim . end1 - m_zoomAnim . end0 ) * v ) ;
}
}
m_callstackBuzzAnim . Update ( io . DeltaTime ) ;
2020-02-29 17:15:59 +00:00
m_sampleParentBuzzAnim . Update ( io . DeltaTime ) ;
2019-08-28 18:27:39 +00:00
m_callstackTreeBuzzAnim . Update ( io . DeltaTime ) ;
m_zoneinfoBuzzAnim . Update ( io . DeltaTime ) ;
m_findZoneBuzzAnim . Update ( io . DeltaTime ) ;
m_optionsLockBuzzAnim . Update ( io . DeltaTime ) ;
m_lockInfoAnim . Update ( io . DeltaTime ) ;
m_statBuzzAnim . Update ( io . DeltaTime ) ;
2021-08-18 22:24:11 +00:00
if ( m_firstFrame )
{
const auto now = std : : chrono : : high_resolution_clock : : now ( ) ;
if ( m_firstFrameTime . time_since_epoch ( ) . count ( ) = = 0 )
{
m_firstFrameTime = now ;
}
else
{
if ( std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( now - m_firstFrameTime ) . count ( ) > 500 )
{
m_firstFrame = false ;
2022-08-20 15:02:29 +00:00
m_tc . FirstFrameExpired ( ) ;
2021-08-18 22:24:11 +00:00
}
}
}
2020-05-23 14:40:15 +00:00
if ( m_reactToCrash )
{
auto & crash = m_worker . GetCrashEvent ( ) ;
if ( crash . thread ! = 0 )
{
m_reactToCrash = false ;
ImGui : : OpenPopup ( " Application crashed! " ) ;
}
}
if ( ImGui : : BeginPopupModal ( " Application crashed! " , nullptr , ImGuiWindowFlags_AlwaysAutoResize ) )
{
auto & crash = m_worker . GetCrashEvent ( ) ;
assert ( crash . thread ! = 0 ) ;
ImGui : : TextUnformatted ( ICON_FA_SKULL ) ;
ImGui : : SameLine ( ) ;
TextColoredUnformatted ( 0xFF4444FF , " Application has crashed " ) ;
ImGui : : SameLine ( ) ;
ImGui : : TextUnformatted ( ICON_FA_SKULL ) ;
ImGui : : Separator ( ) ;
TextFocused ( " Time: " , TimeToString ( crash . time ) ) ;
TextFocused ( " Thread: " , m_worker . GetThreadName ( crash . thread ) ) ;
ImGui : : SameLine ( ) ;
ImGui : : TextDisabled ( " (%s) " , RealToString ( crash . thread ) ) ;
2021-11-06 18:18:33 +00:00
if ( m_worker . IsThreadFiber ( crash . thread ) )
{
ImGui : : SameLine ( ) ;
TextColoredUnformatted ( ImVec4 ( 0.2f , 0.6f , 0.2f , 1.f ) , " Fiber " ) ;
}
2020-05-23 14:40:15 +00:00
TextFocused ( " Reason: " , m_worker . GetString ( crash . message ) ) ;
if ( crash . callstack ! = 0 )
{
bool hilite = m_callstackInfoWindow = = crash . callstack ;
if ( hilite )
{
SetButtonHighlightColor ( ) ;
}
if ( ImGui : : Button ( ICON_FA_ALIGN_JUSTIFY " Call stack " ) )
{
m_callstackInfoWindow = crash . callstack ;
}
if ( hilite )
{
ImGui : : PopStyleColor ( 3 ) ;
}
if ( ImGui : : IsItemHovered ( ) )
{
CallstackTooltip ( crash . callstack ) ;
}
}
ImGui : : Separator ( ) ;
if ( ImGui : : Button ( ICON_FA_MICROSCOPE " Focus " ) ) CenterAtTime ( crash . time ) ;
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( " Dismiss " ) ) ImGui : : CloseCurrentPopup ( ) ;
ImGui : : EndPopup ( ) ;
}
2020-11-18 00:23:46 +00:00
if ( m_reactToLostConnection & & ! m_worker . IsConnected ( ) )
{
m_reactToLostConnection = false ;
2021-04-01 18:16:47 +00:00
const auto inFlight = m_worker . GetSendInFlight ( ) ;
if ( inFlight > 1 | | ( inFlight = = 1 & & ! m_worker . WasDisconnectIssued ( ) ) )
2020-11-18 00:23:46 +00:00
{
ImGui : : OpenPopup ( " Connection lost! " ) ;
}
}
if ( ImGui : : BeginPopupModal ( " Connection lost! " , nullptr , ImGuiWindowFlags_AlwaysAutoResize ) )
{
2022-04-25 21:29:44 +00:00
ImGui : : PushFont ( m_bigFont ) ;
2020-11-18 00:23:46 +00:00
TextCentered ( ICON_FA_PLUG ) ;
2022-04-25 21:29:44 +00:00
ImGui : : PopFont ( ) ;
2020-11-18 00:23:46 +00:00
ImGui : : TextUnformatted (
" Connection to the profiled application was lost \n "
" before all required profiling data could be retrieved. \n "
" This will result in missing source locations, \n "
" unresolved stack frames, etc. " ) ;
ImGui : : Separator ( ) ;
if ( ImGui : : Button ( " Dismiss " ) ) ImGui : : CloseCurrentPopup ( ) ;
ImGui : : EndPopup ( ) ;
}
2019-08-28 18:27:39 +00:00
return keepOpen ;
}
2018-08-17 13:33:12 +00:00
void View : : DrawTextEditor ( )
{
2021-11-18 18:20:45 +00:00
const auto scale = GetScale ( ) ;
ImGui : : SetNextWindowSize ( ImVec2 ( 1800 * scale , 800 * scale ) , ImGuiCond_FirstUseEver ) ;
2018-08-17 13:33:12 +00:00
bool show = true ;
2020-04-12 15:11:51 +00:00
ImGui : : Begin ( " Source view " , & show , ImGuiWindowFlags_NoScrollbar ) ;
2021-11-22 00:15:22 +00:00
if ( ! ImGui : : GetCurrentWindowRead ( ) - > SkipItems )
{
2022-08-15 20:48:00 +00:00
m_sourceView - > UpdateFont ( m_fixedFont , m_smallFont , m_bigFont ) ;
2021-11-22 00:15:22 +00:00
m_sourceView - > Render ( m_worker , * this ) ;
}
2018-08-17 13:33:12 +00:00
ImGui : : End ( ) ;
2020-03-22 19:53:59 +00:00
if ( ! show ) m_sourceViewFile = nullptr ;
2018-08-17 13:33:12 +00:00
}
2019-06-26 19:01:54 +00:00
void View : : CrashTooltip ( )
{
auto & crash = m_worker . GetCrashEvent ( ) ;
ImGui : : BeginTooltip ( ) ;
2019-08-15 19:04:20 +00:00
TextFocused ( " Time: " , TimeToString ( crash . time ) ) ;
2019-06-26 19:01:54 +00:00
TextFocused ( " Reason: " , m_worker . GetString ( crash . message ) ) ;
ImGui : : EndTooltip ( ) ;
}
2021-03-27 12:25:21 +00:00
void View : : DrawSourceTooltip ( const char * filename , uint32_t srcline , int before , int after , bool separateTooltip )
{
2021-03-27 13:09:18 +00:00
if ( ! filename ) return ;
2021-03-27 12:25:21 +00:00
if ( ! SourceFileValid ( filename , m_worker . GetCaptureTime ( ) , * this , m_worker ) ) return ;
m_srcHintCache . Parse ( filename , m_worker , * this ) ;
if ( m_srcHintCache . empty ( ) ) return ;
2022-04-26 19:11:38 +00:00
ImGui : : PushStyleVar ( ImGuiStyleVar_ItemSpacing , ImVec2 ( 0 , 0 ) ) ;
2021-03-27 12:25:21 +00:00
if ( separateTooltip ) ImGui : : BeginTooltip ( ) ;
2022-04-25 21:29:44 +00:00
ImGui : : PushFont ( m_fixedFont ) ;
2021-03-27 12:25:21 +00:00
auto & lines = m_srcHintCache . get ( ) ;
const int start = std : : max ( 0 , ( int ) srcline - ( before + 1 ) ) ;
const int end = std : : min < int > ( m_srcHintCache . get ( ) . size ( ) , srcline + after ) ;
2021-03-27 12:55:22 +00:00
bool first = true ;
int bottomEmpty = 0 ;
2021-03-27 12:25:21 +00:00
for ( int i = start ; i < end ; i + + )
{
auto & line = lines [ i ] ;
if ( line . begin = = line . end )
{
2021-03-27 12:55:22 +00:00
if ( ! first ) bottomEmpty + + ;
2021-03-27 12:25:21 +00:00
}
else
{
2021-03-27 12:55:22 +00:00
first = false ;
while ( bottomEmpty > 0 )
{
ImGui : : TextUnformatted ( " " ) ;
bottomEmpty - - ;
}
2021-03-27 12:25:21 +00:00
auto ptr = line . begin ;
auto it = line . tokens . begin ( ) ;
while ( ptr < line . end )
{
if ( it = = line . tokens . end ( ) )
{
ImGui : : TextUnformatted ( ptr , line . end ) ;
ImGui : : SameLine ( 0 , 0 ) ;
break ;
}
if ( ptr < it - > begin )
{
ImGui : : TextUnformatted ( ptr , it - > begin ) ;
ImGui : : SameLine ( 0 , 0 ) ;
}
TextColoredUnformatted ( i = = srcline - 1 ? SyntaxColors [ ( int ) it - > color ] : SyntaxColorsDimmed [ ( int ) it - > color ] , it - > begin , it - > end ) ;
ImGui : : SameLine ( 0 , 0 ) ;
ptr = it - > end ;
+ + it ;
}
ImGui : : ItemSize ( ImVec2 ( 0 , 0 ) , 0 ) ;
}
}
2022-04-25 21:29:44 +00:00
ImGui : : PopFont ( ) ;
2021-03-27 12:25:21 +00:00
if ( separateTooltip ) ImGui : : EndTooltip ( ) ;
2022-04-26 19:11:38 +00:00
ImGui : : PopStyleVar ( ) ;
2021-03-27 12:25:21 +00:00
}
2021-05-15 13:50:20 +00:00
bool View : : Save ( const char * fn , FileWrite : : Compression comp , int zlevel , bool buildDict )
2021-05-15 12:25:45 +00:00
{
std : : unique_ptr < FileWrite > f ( FileWrite : : Open ( fn , comp , zlevel ) ) ;
if ( ! f ) return false ;
m_userData . StateShouldBePreserved ( ) ;
m_saveThreadState . store ( SaveThreadState : : Saving , std : : memory_order_relaxed ) ;
2021-05-15 13:50:20 +00:00
m_saveThread = std : : thread ( [ this , f { std : : move ( f ) } , buildDict ] {
2021-05-15 12:25:45 +00:00
std : : lock_guard < std : : mutex > lock ( m_worker . GetDataLock ( ) ) ;
2021-05-15 13:50:20 +00:00
m_worker . Write ( * f , buildDict ) ;
2021-05-15 12:25:45 +00:00
f - > Finish ( ) ;
const auto stats = f - > GetCompressionStatistics ( ) ;
m_srcFileBytes . store ( stats . first , std : : memory_order_relaxed ) ;
m_dstFileBytes . store ( stats . second , std : : memory_order_relaxed ) ;
m_saveThreadState . store ( SaveThreadState : : NeedsJoin , std : : memory_order_release ) ;
} ) ;
return true ;
}
2017-09-12 23:33:50 +00:00
}