2018-10-23 17:44:51 +00:00
# include <algorithm>
2018-08-17 15:24:50 +00:00
# include <assert.h>
2020-05-13 17:20:20 +00:00
# include <atomic>
2019-06-17 17:34:48 +00:00
# include <chrono>
2018-07-28 16:50:22 +00:00
# include <inttypes.h>
2024-03-15 19:19:32 +00:00
# define IMGUI_DEFINE_MATH_OPERATORS 1
2017-09-15 19:25:47 +00:00
# include <imgui.h>
2019-06-26 16:41:42 +00:00
# include <mutex>
2018-10-23 17:39:09 +00:00
# include <stdint.h>
2017-09-15 19:25:47 +00:00
# include <stdio.h>
2018-07-15 18:10:34 +00:00
# include <stdlib.h>
2018-08-31 17:38:05 +00:00
# include <string>
2018-10-23 17:39:09 +00:00
# include <unordered_map>
2017-09-15 19:37:28 +00:00
# include <memory>
2017-10-18 21:18:32 +00:00
# include <sys/stat.h>
2019-06-02 17:39:07 +00:00
# include <locale.h>
2017-09-15 19:37:28 +00:00
2021-08-22 11:11:26 +00:00
# ifdef _WIN32
# include <windows.h>
# endif
2019-06-02 15:51:58 +00:00
# define STB_IMAGE_IMPLEMENTATION
# define STBI_ONLY_PNG
# include "stb_image.h"
2022-07-25 23:35:19 +00:00
# define STB_IMAGE_RESIZE_IMPLEMENTATION
# include "stb_image_resize.h"
2019-06-02 15:51:58 +00:00
2023-05-01 13:13:58 +00:00
# include "ini.h"
2022-07-17 11:41:40 +00:00
# include "../../public/common/TracyProtocol.hpp"
2022-08-27 14:05:36 +00:00
# include "../../public/common/TracyVersion.hpp"
2024-03-17 12:15:54 +00:00
# include "profiler/TracyBadVersion.hpp"
# include "profiler/TracyConfig.hpp"
# include "profiler/TracyFileselector.hpp"
# include "profiler/TracyImGui.hpp"
# include "profiler/TracyMouse.hpp"
# include "profiler/TracyProtoHistory.hpp"
# include "profiler/TracyStorage.hpp"
# include "profiler/TracyTexture.hpp"
# include "profiler/TracyView.hpp"
# include "profiler/TracyWeb.hpp"
# include "profiler/IconsFontAwesome6.h"
2018-10-23 17:39:09 +00:00
# include "../../server/tracy_pdqsort.h"
2020-01-28 20:49:36 +00:00
# include "../../server/tracy_robin_hood.h"
2020-09-10 19:52:43 +00:00
# include "../../server/TracyFileHeader.hpp"
2017-09-30 14:58:02 +00:00
# include "../../server/TracyFileRead.hpp"
2019-06-18 18:51:12 +00:00
# include "../../server/TracyPrint.hpp"
2018-07-28 16:07:55 +00:00
# include "../../server/TracyWorker.hpp"
2018-07-29 12:24:24 +00:00
2019-06-02 16:03:56 +00:00
# include "icon.hpp"
2023-04-29 11:10:58 +00:00
# include "zigzag01.hpp"
# include "zigzag02.hpp"
# include "zigzag04.hpp"
# include "zigzag08.hpp"
# include "zigzag16.hpp"
# include "zigzag32.hpp"
2022-07-25 21:24:59 +00:00
2022-07-26 22:57:42 +00:00
# include "Backend.hpp"
2022-07-25 20:57:20 +00:00
# include "ConnectionHistory.hpp"
2022-07-25 21:24:59 +00:00
# include "Filters.hpp"
# include "Fonts.hpp"
2020-09-12 10:46:00 +00:00
# include "HttpRequest.hpp"
2022-11-27 20:53:35 +00:00
# include "IsElevated.hpp"
2022-07-26 22:57:42 +00:00
# include "ImGuiContext.hpp"
2022-07-24 23:39:13 +00:00
# include "ResolvService.hpp"
2022-07-25 18:17:13 +00:00
# include "RunQueue.hpp"
2022-07-25 19:48:06 +00:00
2018-07-27 23:03:26 +00:00
2019-06-17 17:34:48 +00:00
struct ClientData
{
int64_t time ;
uint32_t protocolVersion ;
2020-09-20 20:15:10 +00:00
int32_t activeTime ;
2020-10-02 16:51:54 +00:00
uint16_t port ;
2022-10-09 19:59:18 +00:00
uint64_t pid ;
2019-06-17 17:34:48 +00:00
std : : string procName ;
2019-06-17 17:45:36 +00:00
std : : string address ;
2019-06-17 17:34:48 +00:00
} ;
2020-01-10 01:10:07 +00:00
enum class ViewShutdown { False , True , Join } ;
2020-03-08 13:51:28 +00:00
static tracy : : unordered_flat_map < uint64_t , ClientData > clients ;
2020-01-10 01:10:07 +00:00
static std : : unique_ptr < tracy : : View > view ;
static tracy : : BadVersionState badVer ;
2020-10-02 16:51:54 +00:00
static uint16_t port = 8086 ;
2020-01-10 01:10:07 +00:00
static const char * connectTo = nullptr ;
static char title [ 128 ] ;
2020-09-12 11:22:02 +00:00
static std : : thread loadThread , updateThread , updateNotesThread ;
2020-01-10 01:10:07 +00:00
static std : : unique_ptr < tracy : : UdpListen > broadcastListen ;
static std : : mutex resolvLock ;
2020-01-28 20:49:36 +00:00
static tracy : : unordered_flat_map < std : : string , std : : string > resolvMap ;
2020-01-10 01:10:07 +00:00
static ResolvService resolv ( port ) ;
static char addr [ 1024 ] = { " 127.0.0.1 " } ;
2022-07-25 20:57:20 +00:00
static ConnectionHistory * connHist ;
2020-05-13 17:20:20 +00:00
static std : : atomic < ViewShutdown > viewShutdown { ViewShutdown : : False } ;
2020-01-10 01:10:07 +00:00
static double animTime = 0 ;
static float dpiScale = 1.f ;
2024-01-24 08:34:23 +00:00
static bool dpiScaleOverriddenFromEnv = false ;
2024-03-01 23:21:08 +00:00
static float userScale = 1.f ;
2024-03-15 19:19:32 +00:00
static float prevScale = 1.f ;
2024-03-15 19:25:00 +00:00
static int dpiChanged = 0 ;
2024-03-16 00:16:25 +00:00
static bool dpiFirstSetup = true ;
2022-07-25 21:24:59 +00:00
static Filters * filt ;
2022-07-25 18:17:13 +00:00
static RunQueue mainThreadTasks ;
2020-09-10 19:40:19 +00:00
static uint32_t updateVersion = 0 ;
2020-09-12 11:22:02 +00:00
static bool showReleaseNotes = false ;
static std : : string releaseNotes ;
2022-07-25 23:38:19 +00:00
static uint8_t * iconPx ;
static int iconX , iconY ;
2022-07-25 23:49:50 +00:00
static void * iconTex ;
2022-07-25 23:58:50 +00:00
static int iconTexSz ;
2023-04-29 11:10:58 +00:00
static uint8_t * zigzagPx [ 6 ] ;
static int zigzagX [ 6 ] , zigzagY [ 6 ] ;
2023-04-27 21:16:45 +00:00
void * zigzagTex ;
2022-07-26 22:57:42 +00:00
static Backend * bptr ;
static bool s_customTitle = false ;
2022-11-27 20:53:35 +00:00
static bool s_isElevated = false ;
2023-05-01 12:41:38 +00:00
static tracy : : Config s_config ;
2022-07-26 22:57:42 +00:00
static void SetWindowTitleCallback ( const char * title )
{
char tmp [ 1024 ] ;
sprintf ( tmp , " %s - Tracy Profiler %i.%i.%i " , title , tracy : : Version : : Major , tracy : : Version : : Minor , tracy : : Version : : Patch ) ;
bptr - > SetTitle ( tmp ) ;
s_customTitle = true ;
}
2022-10-13 17:31:47 +00:00
static void AttentionCallback ( )
{
bptr - > Attention ( ) ;
}
2022-07-26 22:57:42 +00:00
static void DrawContents ( ) ;
2020-08-15 12:59:16 +00:00
2023-04-16 14:44:18 +00:00
static void RunOnMainThread ( const std : : function < void ( ) > & cb , bool forceDelay = false )
2020-08-15 12:59:16 +00:00
{
2022-07-25 18:17:13 +00:00
mainThreadTasks . Queue ( cb , forceDelay ) ;
2020-08-15 12:59:16 +00:00
}
2020-01-10 01:10:07 +00:00
2024-03-15 19:19:32 +00:00
static void ScaleWindow ( ImGuiWindow * window , float scale )
{
ImVec2 origin = window - > Viewport - > Pos ;
window - > Pos = ImFloor ( ( window - > Pos - origin ) * scale + origin ) ;
window - > Size = ImTrunc ( window - > Size * scale ) ;
window - > SizeFull = ImTrunc ( window - > SizeFull * scale ) ;
window - > ContentSize = ImTrunc ( window - > ContentSize * scale ) ;
}
2024-03-01 23:21:08 +00:00
static void SetupDPIScale ( )
2021-11-18 21:14:31 +00:00
{
2024-03-01 23:30:50 +00:00
auto scale = dpiScale * userScale ;
2024-03-01 23:21:08 +00:00
2024-03-16 00:16:25 +00:00
if ( ! dpiFirstSetup & & prevScale = = scale ) return ;
dpiFirstSetup = false ;
2024-03-15 19:25:00 +00:00
dpiChanged = 2 ;
2024-03-15 19:19:32 +00:00
2024-03-01 22:43:53 +00:00
LoadFonts ( scale ) ;
if ( view ) view - > UpdateFont ( s_fixedWidth , s_smallFont , s_bigFont ) ;
2021-11-18 21:14:31 +00:00
2023-08-23 10:24:22 +00:00
# ifdef __APPLE__
// No need to upscale the style on macOS, but we need to downscale the fonts.
ImGuiIO & io = ImGui : : GetIO ( ) ;
io . FontGlobalScale = 1.0f / dpiScale ;
scale = 1.0f ;
# endif
2021-11-18 21:14:31 +00:00
auto & style = ImGui : : GetStyle ( ) ;
2021-11-18 21:47:58 +00:00
style = ImGuiStyle ( ) ;
ImGui : : StyleColorsDark ( ) ;
2021-11-18 21:14:31 +00:00
style . WindowBorderSize = 1.f * scale ;
style . FrameBorderSize = 1.f * scale ;
style . FrameRounding = 5.f ;
style . Colors [ ImGuiCol_ScrollbarBg ] = ImVec4 ( 1 , 1 , 1 , 0.03f ) ;
style . Colors [ ImGuiCol_Header ] = ImVec4 ( 0.26f , 0.59f , 0.98f , 0.25f ) ;
style . Colors [ ImGuiCol_HeaderHovered ] = ImVec4 ( 0.26f , 0.59f , 0.98f , 0.35f ) ;
style . Colors [ ImGuiCol_HeaderActive ] = ImVec4 ( 0.26f , 0.59f , 0.98f , 0.45f ) ;
style . ScaleAllSizes ( scale ) ;
2022-07-25 23:49:50 +00:00
2022-07-25 23:58:50 +00:00
const auto ty = int ( 80 * scale ) ;
iconTexSz = ty ;
2022-07-25 23:49:50 +00:00
auto scaleIcon = new uint8_t [ 4 * ty * ty ] ;
stbir_resize_uint8 ( iconPx , iconX , iconY , 0 , scaleIcon , ty , ty , 0 , 4 ) ;
tracy : : UpdateTextureRGBA ( iconTex , scaleIcon , ty , ty ) ;
delete [ ] scaleIcon ;
2024-03-15 19:19:32 +00:00
const auto ratio = scale / prevScale ;
prevScale = scale ;
auto ctx = ImGui : : GetCurrentContext ( ) ;
for ( auto & w : ctx - > Windows ) ScaleWindow ( w , ratio ) ;
2021-11-18 21:14:31 +00:00
}
2024-03-01 22:43:53 +00:00
static void SetupScaleCallback ( float scale )
2021-11-18 21:22:11 +00:00
{
2024-03-01 23:21:08 +00:00
userScale = scale ;
RunOnMainThread ( [ ] { SetupDPIScale ( ) ; } , true ) ;
2021-11-18 21:22:11 +00:00
}
2024-03-24 16:38:45 +00:00
static int IsBusy ( )
{
if ( loadThread . joinable ( ) ) return 2 ;
if ( view & & ! view - > IsBackgroundDone ( ) ) return 1 ;
return 0 ;
}
2023-05-01 13:13:58 +00:00
static void LoadConfig ( )
{
const auto fn = tracy : : GetSavePath ( " tracy.ini " ) ;
auto ini = ini_load ( fn ) ;
if ( ! ini ) return ;
int v ;
if ( ini_sget ( ini , " core " , " threadedRendering " , " %d " , & v ) ) s_config . threadedRendering = v ;
2023-05-01 17:07:49 +00:00
if ( ini_sget ( ini , " timeline " , " targetFps " , " %d " , & v ) & & v > = 1 & & v < 10000 ) s_config . targetFps = v ;
2023-05-01 13:13:58 +00:00
ini_free ( ini ) ;
}
static bool SaveConfig ( )
{
const auto fn = tracy : : GetSavePath ( " tracy.ini " ) ;
FILE * f = fopen ( fn , " wb " ) ;
if ( ! f ) return false ;
fprintf ( f , " [core] \n " ) ;
fprintf ( f , " threadedRendering = %i \n " , ( int ) s_config . threadedRendering ) ;
2023-05-01 17:07:49 +00:00
fprintf ( f , " \n [timeline] \n " ) ;
fprintf ( f , " targetFps = %i \n " , s_config . targetFps ) ;
2023-05-01 13:13:58 +00:00
fclose ( f ) ;
return true ;
}
2024-01-24 08:34:23 +00:00
static void ScaleChanged ( float scale )
{
if ( dpiScaleOverriddenFromEnv ) return ;
if ( dpiScale = = scale ) return ;
dpiScale = scale ;
2024-03-01 23:21:08 +00:00
SetupDPIScale ( ) ;
2024-01-24 08:34:23 +00:00
}
2018-03-24 21:20:06 +00:00
int main ( int argc , char * * argv )
2017-09-15 19:25:47 +00:00
{
2019-02-22 01:41:13 +00:00
sprintf ( title , " Tracy Profiler %i.%i.%i " , tracy : : Version : : Major , tracy : : Version : : Minor , tracy : : Version : : Patch ) ;
2018-07-29 12:24:24 +00:00
2022-04-26 23:51:30 +00:00
std : : unique_ptr < tracy : : FileRead > initFileOpen ;
2022-10-01 22:41:08 +00:00
# ifdef __EMSCRIPTEN__
initFileOpen = std : : unique_ptr < tracy : : FileRead > ( tracy : : FileRead : : Open ( " embed.tracy " ) ) ;
# endif
2022-04-26 23:51:30 +00:00
if ( argc = = 2 )
{
if ( strcmp ( argv [ 1 ] , " --help " ) = = 0 )
{
printf ( " %s \n \n " , title ) ;
printf ( " Usage: \n \n " ) ;
printf ( " Open trace file stored on disk: \n " ) ;
printf ( " %s file.tracy \n \n " , argv [ 0 ] ) ;
printf ( " Connect to a running client: \n " ) ;
printf ( " %s -a address [-p port] \n " , argv [ 0 ] ) ;
exit ( 0 ) ;
}
2024-02-03 15:25:01 +00:00
try
{
initFileOpen = std : : unique_ptr < tracy : : FileRead > ( tracy : : FileRead : : Open ( argv [ 1 ] ) ) ;
}
catch ( const tracy : : UnsupportedVersion & e )
{
fprintf ( stderr , " The file you are trying to open is from the future version. \n " ) ;
exit ( 1 ) ;
}
catch ( const tracy : : NotTracyDump & e )
{
fprintf ( stderr , " The file you are trying to open is not a tracy dump. \n " ) ;
exit ( 1 ) ;
}
catch ( const tracy : : LegacyVersion & e )
{
fprintf ( stderr , " The file you are trying to open is from a legacy version. \n " ) ;
exit ( 1 ) ;
}
2022-04-26 23:51:30 +00:00
if ( ! initFileOpen )
{
fprintf ( stderr , " Cannot open trace file: %s \n " , argv [ 1 ] ) ;
exit ( 1 ) ;
}
}
else
{
while ( argc > = 3 )
{
if ( strcmp ( argv [ 1 ] , " -a " ) = = 0 )
{
connectTo = argv [ 2 ] ;
}
else if ( strcmp ( argv [ 1 ] , " -p " ) = = 0 )
{
port = ( uint16_t ) atoi ( argv [ 2 ] ) ;
}
else
{
fprintf ( stderr , " Bad parameter: %s " , argv [ 1 ] ) ;
exit ( 1 ) ;
}
argc - = 2 ;
argv + = 2 ;
}
}
2022-07-25 20:57:20 +00:00
ConnectionHistory connHistory ;
2022-07-25 21:24:59 +00:00
Filters filters ;
2022-07-25 20:57:20 +00:00
connHist = & connHistory ;
2022-07-25 21:24:59 +00:00
filt = & filters ;
2018-10-23 17:39:09 +00:00
2022-10-08 12:44:53 +00:00
# ifndef __EMSCRIPTEN__
2020-09-10 19:40:19 +00:00
updateThread = std : : thread ( [ ] {
2020-09-14 20:35:03 +00:00
HttpRequest ( " nereid.pl " , " /tracy/version " , 8099 , [ ] ( int size , char * data ) {
2020-09-12 10:46:00 +00:00
if ( size = = 4 )
{
uint32_t ver ;
memcpy ( & ver , data , 4 ) ;
2022-09-27 23:24:41 +00:00
RunOnMainThread ( [ ver ] { updateVersion = ver ; tracy : : s_wasActive = true ; } ) ;
2020-09-12 10:46:00 +00:00
}
delete [ ] data ;
} ) ;
2020-09-10 19:40:19 +00:00
} ) ;
2022-10-08 12:44:53 +00:00
# endif
2020-09-10 19:40:19 +00:00
2022-08-07 15:13:38 +00:00
auto iconThread = std : : thread ( [ ] {
iconPx = stbi_load_from_memory ( ( const stbi_uc * ) Icon_data , Icon_size , & iconX , & iconY , nullptr , 4 ) ;
2023-04-29 11:10:58 +00:00
zigzagPx [ 0 ] = stbi_load_from_memory ( ( const stbi_uc * ) ZigZag32_data , ZigZag32_size , & zigzagX [ 0 ] , & zigzagY [ 0 ] , nullptr , 4 ) ;
zigzagPx [ 1 ] = stbi_load_from_memory ( ( const stbi_uc * ) ZigZag16_data , ZigZag16_size , & zigzagX [ 1 ] , & zigzagY [ 1 ] , nullptr , 4 ) ;
zigzagPx [ 2 ] = stbi_load_from_memory ( ( const stbi_uc * ) ZigZag08_data , ZigZag08_size , & zigzagX [ 2 ] , & zigzagY [ 2 ] , nullptr , 4 ) ;
zigzagPx [ 3 ] = stbi_load_from_memory ( ( const stbi_uc * ) ZigZag04_data , ZigZag04_size , & zigzagX [ 3 ] , & zigzagY [ 3 ] , nullptr , 4 ) ;
zigzagPx [ 4 ] = stbi_load_from_memory ( ( const stbi_uc * ) ZigZag02_data , ZigZag02_size , & zigzagX [ 4 ] , & zigzagY [ 4 ] , nullptr , 4 ) ;
zigzagPx [ 5 ] = stbi_load_from_memory ( ( const stbi_uc * ) ZigZag01_data , ZigZag01_size , & zigzagX [ 5 ] , & zigzagY [ 5 ] , nullptr , 4 ) ;
2022-08-07 15:13:38 +00:00
} ) ;
2022-07-25 23:38:19 +00:00
2023-05-01 13:13:58 +00:00
LoadConfig ( ) ;
2022-07-26 22:57:42 +00:00
ImGuiTracyContext imguiContext ;
2024-03-24 16:39:55 +00:00
Backend backend ( title , DrawContents , ScaleChanged , IsBusy , & mainThreadTasks ) ;
2022-10-15 10:56:19 +00:00
tracy : : InitTexture ( ) ;
2022-10-15 10:16:18 +00:00
iconTex = tracy : : MakeTexture ( ) ;
2023-04-27 19:59:43 +00:00
zigzagTex = tracy : : MakeTexture ( true ) ;
2022-08-07 15:13:38 +00:00
iconThread . join ( ) ;
2022-07-26 22:57:42 +00:00
backend . SetIcon ( iconPx , iconX , iconY ) ;
bptr = & backend ;
2017-09-15 19:25:47 +00:00
2022-07-26 22:57:42 +00:00
dpiScale = backend . GetDpiScale ( ) ;
2021-06-16 22:52:50 +00:00
const auto envDpiScale = getenv ( " TRACY_DPI_SCALE " ) ;
if ( envDpiScale )
{
const auto cnv = atof ( envDpiScale ) ;
2024-01-24 08:34:23 +00:00
if ( cnv ! = 0 )
{
dpiScale = cnv ;
dpiScaleOverriddenFromEnv = true ;
}
2021-06-16 22:52:50 +00:00
}
2024-03-01 23:21:08 +00:00
SetupDPIScale ( ) ;
2018-01-13 12:59:16 +00:00
2023-04-29 11:10:58 +00:00
tracy : : UpdateTextureRGBAMips ( zigzagTex , ( void * * ) zigzagPx , zigzagX , zigzagY , 6 ) ;
for ( auto & v : zigzagPx ) free ( v ) ;
2023-04-27 19:59:43 +00:00
2022-04-26 23:51:30 +00:00
if ( initFileOpen )
2020-05-23 14:49:27 +00:00
{
2023-05-01 12:41:38 +00:00
view = std : : make_unique < tracy : : View > ( RunOnMainThread , * initFileOpen , s_fixedWidth , s_smallFont , s_bigFont , SetWindowTitleCallback , SetupScaleCallback , AttentionCallback , s_config ) ;
2022-04-26 23:51:30 +00:00
initFileOpen . reset ( ) ;
2020-05-23 14:49:27 +00:00
}
2022-04-26 23:51:30 +00:00
else if ( connectTo )
2020-05-23 14:49:27 +00:00
{
2023-05-01 12:41:38 +00:00
view = std : : make_unique < tracy : : View > ( RunOnMainThread , connectTo , port , s_fixedWidth , s_smallFont , s_bigFont , SetWindowTitleCallback , SetupScaleCallback , AttentionCallback , s_config ) ;
2020-05-23 14:49:27 +00:00
}
2022-10-05 20:50:17 +00:00
tracy : : Fileselector : : Init ( ) ;
2022-11-27 20:53:35 +00:00
s_isElevated = IsElevated ( ) ;
2022-04-20 16:24:00 +00:00
2022-07-26 22:57:42 +00:00
backend . Show ( ) ;
backend . Run ( ) ;
2020-01-10 01:10:07 +00:00
2020-07-19 12:39:50 +00:00
if ( loadThread . joinable ( ) ) loadThread . join ( ) ;
2020-09-10 19:40:19 +00:00
if ( updateThread . joinable ( ) ) updateThread . join ( ) ;
2020-09-12 11:22:02 +00:00
if ( updateNotesThread . joinable ( ) ) updateNotesThread . join ( ) ;
2020-07-19 12:50:09 +00:00
view . reset ( ) ;
2020-07-19 12:39:50 +00:00
2023-04-27 19:59:43 +00:00
tracy : : FreeTexture ( zigzagTex , RunOnMainThread ) ;
2022-07-25 23:49:50 +00:00
tracy : : FreeTexture ( iconTex , RunOnMainThread ) ;
2022-07-26 22:57:42 +00:00
free ( iconPx ) ;
2022-04-20 16:24:00 +00:00
2022-10-05 20:50:17 +00:00
tracy : : Fileselector : : Shutdown ( ) ;
2022-04-20 16:24:00 +00:00
2020-01-10 01:10:07 +00:00
return 0 ;
}
2023-05-07 14:11:42 +00:00
static void UpdateBroadcastClients ( )
2020-01-10 01:10:07 +00:00
{
if ( ! view )
{
const auto time = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( std : : chrono : : system_clock : : now ( ) . time_since_epoch ( ) ) . count ( ) ;
if ( ! broadcastListen )
{
broadcastListen = std : : make_unique < tracy : : UdpListen > ( ) ;
if ( ! broadcastListen - > Listen ( port ) )
2019-06-17 17:34:48 +00:00
{
2020-01-10 01:10:07 +00:00
broadcastListen . reset ( ) ;
2019-06-17 17:34:48 +00:00
}
2020-01-10 01:10:07 +00:00
}
else
{
tracy : : IpAddress addr ;
size_t len ;
2020-09-20 20:08:34 +00:00
for ( ; ; )
2019-06-17 17:34:48 +00:00
{
2020-09-20 20:08:34 +00:00
auto msg = broadcastListen - > Read ( len , addr , 0 ) ;
if ( ! msg ) break ;
2020-09-20 20:27:49 +00:00
if ( len > sizeof ( tracy : : BroadcastMessage ) ) continue ;
2022-10-26 21:21:17 +00:00
uint16_t broadcastVersion ;
memcpy ( & broadcastVersion , msg , sizeof ( uint16_t ) ) ;
if ( broadcastVersion < = tracy : : BroadcastVersion )
2020-01-10 01:10:07 +00:00
{
2022-10-26 21:21:17 +00:00
uint32_t protoVer ;
char procname [ tracy : : WelcomeMessageProgramNameSize ] ;
int32_t activeTime ;
uint16_t listenPort ;
uint64_t pid ;
2020-01-10 01:10:07 +00:00
2022-10-26 21:21:17 +00:00
switch ( broadcastVersion )
{
case 3 :
{
tracy : : BroadcastMessage bm ;
memcpy ( & bm , msg , len ) ;
protoVer = bm . protocolVersion ;
strcpy ( procname , bm . programName ) ;
activeTime = bm . activeTime ;
listenPort = bm . listenPort ;
pid = bm . pid ;
break ;
}
case 2 :
{
if ( len > sizeof ( tracy : : BroadcastMessage_v2 ) ) continue ;
tracy : : BroadcastMessage_v2 bm ;
memcpy ( & bm , msg , len ) ;
protoVer = bm . protocolVersion ;
strcpy ( procname , bm . programName ) ;
activeTime = bm . activeTime ;
listenPort = bm . listenPort ;
pid = 0 ;
break ;
}
case 1 :
{
if ( len > sizeof ( tracy : : BroadcastMessage_v1 ) ) continue ;
tracy : : BroadcastMessage_v1 bm ;
memcpy ( & bm , msg , len ) ;
protoVer = bm . protocolVersion ;
strcpy ( procname , bm . programName ) ;
activeTime = bm . activeTime ;
listenPort = bm . listenPort ;
pid = 0 ;
break ;
}
case 0 :
{
if ( len > sizeof ( tracy : : BroadcastMessage_v0 ) ) continue ;
tracy : : BroadcastMessage_v0 bm ;
memcpy ( & bm , msg , len ) ;
protoVer = bm . protocolVersion ;
strcpy ( procname , bm . programName ) ;
activeTime = bm . activeTime ;
listenPort = 8086 ;
pid = 0 ;
break ;
}
default :
assert ( false ) ;
break ;
}
auto address = addr . GetText ( ) ;
2020-01-10 01:10:07 +00:00
const auto ipNumerical = addr . GetNumber ( ) ;
2020-03-08 13:51:28 +00:00
const auto clientId = uint64_t ( ipNumerical ) | ( uint64_t ( listenPort ) < < 32 ) ;
auto it = clients . find ( clientId ) ;
2020-09-20 20:40:38 +00:00
if ( activeTime > = 0 )
2019-06-17 17:34:48 +00:00
{
2020-09-20 20:40:38 +00:00
if ( it = = clients . end ( ) )
2019-06-18 18:26:40 +00:00
{
2020-09-20 20:40:38 +00:00
std : : string ip ( address ) ;
resolvLock . lock ( ) ;
if ( resolvMap . find ( ip ) = = resolvMap . end ( ) )
{
resolvMap . emplace ( ip , ip ) ;
resolv . Query ( ipNumerical , [ ip ] ( std : : string & & name ) {
std : : lock_guard < std : : mutex > lock ( resolvLock ) ;
auto it = resolvMap . find ( ip ) ;
assert ( it ! = resolvMap . end ( ) ) ;
std : : swap ( it - > second , name ) ;
} ) ;
}
resolvLock . unlock ( ) ;
2022-10-09 19:59:18 +00:00
clients . emplace ( clientId , ClientData { time , protoVer , activeTime , listenPort , pid , procname , std : : move ( ip ) } ) ;
2020-09-20 20:40:38 +00:00
}
else
{
it - > second . time = time ;
it - > second . activeTime = activeTime ;
it - > second . port = listenPort ;
2022-10-09 19:59:18 +00:00
it - > second . pid = pid ;
2022-10-09 19:59:10 +00:00
it - > second . protocolVersion = protoVer ;
2020-09-20 20:40:38 +00:00
if ( strcmp ( it - > second . procName . c_str ( ) , procname ) ! = 0 ) it - > second . procName = procname ;
2019-06-18 18:26:40 +00:00
}
2019-06-17 17:34:48 +00:00
}
2020-09-20 20:40:38 +00:00
else if ( it ! = clients . end ( ) )
2019-06-17 17:34:48 +00:00
{
2020-09-20 20:40:38 +00:00
clients . erase ( it ) ;
2019-06-17 17:34:48 +00:00
}
}
}
2020-01-10 01:10:07 +00:00
auto it = clients . begin ( ) ;
while ( it ! = clients . end ( ) )
{
const auto diff = time - it - > second . time ;
if ( diff > 4000 ) // 4s
{
it = clients . erase ( it ) ;
}
else
{
+ + it ;
}
}
}
2022-09-27 23:31:38 +00:00
}
2022-09-27 23:34:20 +00:00
else if ( ! clients . empty ( ) )
{
clients . clear ( ) ;
}
2023-05-07 14:11:42 +00:00
}
2024-03-07 16:49:39 +00:00
static void TextComment ( const char * str )
{
ImGui : : SameLine ( ) ;
ImGui : : PushFont ( s_smallFont ) ;
ImGui : : AlignTextToFramePadding ( ) ;
tracy : : TextDisabledUnformatted ( str ) ;
ImGui : : PopFont ( ) ;
}
2023-05-07 14:11:42 +00:00
static void DrawContents ( )
{
static bool reconnect = false ;
static std : : string reconnectAddr ;
static uint16_t reconnectPort ;
static bool showFilter = false ;
# ifndef __EMSCRIPTEN__
UpdateBroadcastClients ( ) ;
2022-10-08 12:51:21 +00:00
# endif
2022-09-27 23:31:38 +00:00
int display_w , display_h ;
bptr - > NewFrame ( display_w , display_h ) ;
static int activeFrames = 3 ;
2022-09-27 23:34:31 +00:00
if ( tracy : : WasActive ( ) | | ! clients . empty ( ) | | ( view & & view - > WasActive ( ) ) )
2022-09-27 23:31:38 +00:00
{
activeFrames = 3 ;
}
else
{
auto ctx = ImGui : : GetCurrentContext ( ) ;
2022-09-28 15:57:29 +00:00
if ( ctx - > NavWindowingTarget | | ( ctx - > DimBgRatio ! = 0 & & ctx - > DimBgRatio ! = 1 ) )
2022-09-27 23:31:38 +00:00
{
activeFrames = 3 ;
}
else
{
auto & inputQueue = ctx - > InputEventsQueue ;
if ( ! inputQueue . empty ( ) )
{
for ( auto & v : inputQueue )
{
if ( v . Type ! = ImGuiInputEventType_MouseViewport )
{
activeFrames = 3 ;
break ;
}
}
}
}
}
if ( activeFrames = = 0 )
{
std : : this_thread : : sleep_for ( std : : chrono : : milliseconds ( 16 ) ) ;
return ;
}
activeFrames - - ;
ImGui : : NewFrame ( ) ;
tracy : : MouseFrame ( ) ;
setlocale ( LC_NUMERIC , " C " ) ;
if ( ! view )
{
if ( s_customTitle )
{
s_customTitle = false ;
bptr - > SetTitle ( title ) ;
}
2019-06-17 17:34:48 +00:00
2020-01-10 01:10:07 +00:00
auto & style = ImGui : : GetStyle ( ) ;
style . Colors [ ImGuiCol_WindowBg ] = ImVec4 ( 0.129f , 0.137f , 0.11f , 1.f ) ;
2021-04-07 23:35:58 +00:00
ImGui : : Begin ( " Get started " , nullptr , ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse ) ;
2020-01-10 01:10:07 +00:00
char buf [ 128 ] ;
sprintf ( buf , " Tracy Profiler %i.%i.%i " , tracy : : Version : : Major , tracy : : Version : : Minor , tracy : : Version : : Patch ) ;
2022-07-24 23:39:13 +00:00
ImGui : : PushFont ( s_bigFont ) ;
2020-01-10 01:10:07 +00:00
tracy : : TextCentered ( buf ) ;
ImGui : : PopFont ( ) ;
2024-03-15 19:25:00 +00:00
if ( dpiChanged = = 0 )
2020-10-12 00:42:37 +00:00
{
2024-03-15 19:25:00 +00:00
ImGui : : SameLine ( ImGui : : GetWindowContentRegionMax ( ) . x - ImGui : : CalcTextSize ( ICON_FA_WRENCH ) . x - ImGui : : GetStyle ( ) . FramePadding . x * 2 ) ;
if ( ImGui : : Button ( ICON_FA_WRENCH ) )
{
ImGui : : OpenPopup ( " About Tracy " ) ;
}
2020-10-12 00:42:37 +00:00
}
bool keepOpenAbout = true ;
if ( ImGui : : BeginPopupModal ( " About Tracy " , & keepOpenAbout , ImGuiWindowFlags_AlwaysAutoResize ) )
{
2022-07-25 23:58:50 +00:00
tracy : : ImageCentered ( iconTex , ImVec2 ( iconTexSz , iconTexSz ) ) ;
ImGui : : Spacing ( ) ;
2022-07-24 23:39:13 +00:00
ImGui : : PushFont ( s_bigFont ) ;
2020-10-12 00:42:37 +00:00
tracy : : TextCentered ( buf ) ;
ImGui : : PopFont ( ) ;
ImGui : : Spacing ( ) ;
ImGui : : TextUnformatted ( " A real time, nanosecond resolution, remote telemetry, hybrid \n frame and sampling profiler for games and other applications. " ) ;
ImGui : : Spacing ( ) ;
ImGui : : TextUnformatted ( " Created by Bartosz Taudul " ) ;
ImGui : : SameLine ( ) ;
2021-02-10 01:43:05 +00:00
tracy : : TextDisabledUnformatted ( " <wolf@nereid.pl> " ) ;
2024-03-13 00:00:41 +00:00
tracy : : TextDisabledUnformatted ( " Additional authors listed in git history. " ) ;
2020-10-12 00:42:37 +00:00
ImGui : : Separator ( ) ;
2023-05-01 13:28:45 +00:00
if ( ImGui : : TreeNode ( ICON_FA_TOOLBOX " Global settings " ) )
{
2023-05-01 17:07:49 +00:00
ImGui : : PushStyleVar ( ImGuiStyleVar_FramePadding , ImVec2 ( 0 , 0 ) ) ;
2023-05-01 13:28:45 +00:00
ImGui : : TextUnformatted ( " Threaded rendering " ) ;
ImGui : : Indent ( ) ;
if ( ImGui : : RadioButton ( " Enabled " , s_config . threadedRendering ) ) { s_config . threadedRendering = true ; SaveConfig ( ) ; }
ImGui : : SameLine ( ) ;
2023-08-05 10:08:29 +00:00
tracy : : DrawHelpMarker ( " Uses multiple CPU cores for rendering. May affect performance of the profiled application when running on the same machine. " ) ;
2023-05-01 13:28:45 +00:00
if ( ImGui : : RadioButton ( " Disabled " , ! s_config . threadedRendering ) ) { s_config . threadedRendering = false ; SaveConfig ( ) ; }
ImGui : : SameLine ( ) ;
2023-05-01 13:48:33 +00:00
tracy : : DrawHelpMarker ( " Restricts rendering to a single CPU core. Can reduce profiler frame rate. " ) ;
2023-05-01 13:28:45 +00:00
ImGui : : Unindent ( ) ;
2023-05-01 17:07:49 +00:00
ImGui : : Spacing ( ) ;
ImGui : : TextUnformatted ( " Target FPS " ) ;
ImGui : : SameLine ( ) ;
int tmp = s_config . targetFps ;
ImGui : : SetNextItemWidth ( 90 * dpiScale ) ;
if ( ImGui : : InputInt ( " ##targetfps " , & tmp ) ) { s_config . targetFps = std : : clamp ( tmp , 1 , 9999 ) ; SaveConfig ( ) ; }
ImGui : : PopStyleVar ( ) ;
2023-05-01 13:28:45 +00:00
ImGui : : TreePop ( ) ;
}
ImGui : : Separator ( ) ;
2022-09-25 23:15:37 +00:00
ImGui : : PushFont ( s_smallFont ) ;
2020-10-12 00:42:37 +00:00
tracy : : TextFocused ( " Protocol version " , tracy : : RealToString ( tracy : : ProtocolVersion ) ) ;
2022-09-25 23:15:37 +00:00
ImGui : : SameLine ( ) ;
ImGui : : SeparatorEx ( ImGuiSeparatorFlags_Vertical ) ;
ImGui : : SameLine ( ) ;
2020-10-12 00:42:37 +00:00
tracy : : TextFocused ( " Broadcast version " , tracy : : RealToString ( tracy : : BroadcastVersion ) ) ;
2022-09-25 23:15:37 +00:00
ImGui : : SameLine ( ) ;
ImGui : : SeparatorEx ( ImGuiSeparatorFlags_Vertical ) ;
ImGui : : SameLine ( ) ;
2020-10-12 00:42:37 +00:00
tracy : : TextFocused ( " Build date " , __DATE__ " , " __TIME__ ) ;
2022-09-25 23:15:37 +00:00
ImGui : : PopFont ( ) ;
2020-10-12 00:42:37 +00:00
ImGui : : EndPopup ( ) ;
}
2020-01-10 01:10:07 +00:00
ImGui : : Spacing ( ) ;
if ( ImGui : : Button ( ICON_FA_BOOK " Manual " ) )
{
2021-06-04 12:33:12 +00:00
tracy : : OpenWebpage ( " https://github.com/wolfpld/tracy/releases " ) ;
2020-01-10 01:10:07 +00:00
}
ImGui : : SameLine ( ) ;
2022-08-17 10:07:38 +00:00
if ( ImGui : : Button ( ICON_FA_EARTH_AMERICAS " Web " ) )
2020-01-10 01:10:07 +00:00
{
2020-03-29 12:06:54 +00:00
ImGui : : OpenPopup ( " web " ) ;
2020-01-10 01:10:07 +00:00
}
2020-03-29 12:06:54 +00:00
if ( ImGui : : BeginPopup ( " web " ) )
2020-01-10 01:10:07 +00:00
{
2022-08-17 10:07:38 +00:00
if ( ImGui : : Selectable ( ICON_FA_HOUSE_CHIMNEY " Tracy Profiler home page " ) )
2020-03-29 12:06:54 +00:00
{
2021-06-04 12:33:12 +00:00
tracy : : OpenWebpage ( " https://github.com/wolfpld/tracy " ) ;
2020-03-29 12:06:54 +00:00
}
ImGui : : Separator ( ) ;
2024-03-07 16:49:39 +00:00
if ( ImGui : : Selectable ( ICON_FA_VIDEO " An Introduction to Tracy Profiler in C++ - Marcos Slomp - CppCon 2023 " ) )
{
tracy : : OpenWebpage ( " https://youtu.be/ghXk3Bk5F2U?t=37 " ) ;
}
ImGui : : Separator ( ) ;
2022-03-28 19:20:44 +00:00
if ( ImGui : : Selectable ( ICON_FA_VIDEO " New features in v0.8 " ) )
2018-08-03 23:15:56 +00:00
{
2022-03-28 19:20:44 +00:00
tracy : : OpenWebpage ( " https://www.youtube.com/watch?v=30wpRpHTTag " ) ;
2018-08-03 23:15:56 +00:00
}
2024-03-07 16:49:39 +00:00
TextComment ( " 2022-03-28 " ) ;
2022-03-28 19:20:44 +00:00
if ( ImGui : : Selectable ( ICON_FA_VIDEO " New features in v0.7 " ) )
2018-07-15 18:10:41 +00:00
{
2022-03-28 19:20:44 +00:00
tracy : : OpenWebpage ( " https://www.youtube.com/watch?v=_hU7vw00MZ4 " ) ;
2018-07-15 18:10:41 +00:00
}
2024-03-07 16:49:39 +00:00
TextComment ( " 2020-06-11 " ) ;
2022-03-28 19:20:44 +00:00
if ( ImGui : : Selectable ( ICON_FA_VIDEO " New features in v0.6 " ) )
2019-06-11 00:12:34 +00:00
{
2022-03-28 19:20:44 +00:00
tracy : : OpenWebpage ( " https://www.youtube.com/watch?v=uJkrFgriuOo " ) ;
2019-06-11 00:12:34 +00:00
}
2024-03-07 16:49:39 +00:00
TextComment ( " 2019-11-17 " ) ;
2020-03-29 12:06:54 +00:00
if ( ImGui : : Selectable ( ICON_FA_VIDEO " New features in v0.5 " ) )
2018-07-15 18:10:41 +00:00
{
2021-06-04 12:33:12 +00:00
tracy : : OpenWebpage ( " https://www.youtube.com/watch?v=P6E7qLMmzTQ " ) ;
2018-10-09 17:28:24 +00:00
}
2024-03-07 16:49:39 +00:00
TextComment ( " 2019-08-10 " ) ;
2022-03-28 19:20:44 +00:00
if ( ImGui : : Selectable ( ICON_FA_VIDEO " New features in v0.4 " ) )
2018-10-09 17:28:24 +00:00
{
2022-03-28 19:20:44 +00:00
tracy : : OpenWebpage ( " https://www.youtube.com/watch?v=eAkgkaO8B9o " ) ;
2018-07-15 18:10:41 +00:00
}
2024-03-07 16:49:39 +00:00
TextComment ( " 2018-10-09 " ) ;
2022-03-28 19:20:44 +00:00
if ( ImGui : : Selectable ( ICON_FA_VIDEO " New features in v0.3 " ) )
2020-06-11 12:30:08 +00:00
{
2022-03-28 19:20:44 +00:00
tracy : : OpenWebpage ( " https://www.youtube.com/watch?v=3SXpDpDh2Uo " ) ;
}
2024-03-07 16:49:39 +00:00
TextComment ( " 2018-07-03 " ) ;
2022-03-28 19:20:44 +00:00
if ( ImGui : : Selectable ( ICON_FA_VIDEO " Overview of v0.2 " ) )
{
tracy : : OpenWebpage ( " https://www.youtube.com/watch?v=fB5B46lbapc " ) ;
2020-06-11 12:30:08 +00:00
}
2024-03-07 16:49:39 +00:00
TextComment ( " 2018-03-25 " ) ;
2020-01-10 01:10:07 +00:00
ImGui : : EndPopup ( ) ;
}
2020-03-29 12:06:54 +00:00
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( ICON_FA_COMMENT " Chat " ) )
{
2021-06-04 12:33:12 +00:00
tracy : : OpenWebpage ( " https://discord.gg/pk78auc " ) ;
2020-03-29 12:06:54 +00:00
}
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( ICON_FA_HEART " Sponsor " ) )
{
2021-06-04 12:33:12 +00:00
tracy : : OpenWebpage ( " https://github.com/sponsors/wolfpld/ " ) ;
2020-03-29 12:06:54 +00:00
}
2023-04-24 21:57:27 +00:00
if ( updateVersion > tracy : : FileVersion ( tracy : : Version : : Major , tracy : : Version : : Minor , tracy : : Version : : Patch ) )
2020-09-10 19:52:43 +00:00
{
ImGui : : Separator ( ) ;
2020-09-12 11:22:02 +00:00
ImGui : : TextColored ( ImVec4 ( 1 , 1 , 0 , 1 ) , ICON_FA_EXCLAMATION " Update to %i.%i.%i is available! " , ( updateVersion > > 16 ) & 0xFF , ( updateVersion > > 8 ) & 0xFF , updateVersion & 0xFF ) ;
2020-09-10 19:52:43 +00:00
ImGui : : SameLine ( ) ;
2020-09-12 11:22:02 +00:00
if ( ImGui : : SmallButton ( ICON_FA_GIFT " Get it! " ) )
2020-09-10 19:52:43 +00:00
{
2020-09-12 11:22:02 +00:00
showReleaseNotes = true ;
if ( ! updateNotesThread . joinable ( ) )
{
updateNotesThread = std : : thread ( [ ] {
2020-09-14 20:35:03 +00:00
HttpRequest ( " nereid.pl " , " /tracy/notes " , 8099 , [ ] ( int size , char * data ) {
2020-09-12 11:22:02 +00:00
std : : string notes ( data , data + size ) ;
delete [ ] data ;
2023-04-16 14:47:47 +00:00
RunOnMainThread ( [ notes = std : : move ( notes ) ] ( ) mutable { releaseNotes = std : : move ( notes ) ; tracy : : s_wasActive = true ; } ) ;
2020-09-12 11:22:02 +00:00
} ) ;
} ) ;
}
2020-09-10 19:52:43 +00:00
}
}
2022-11-27 21:24:42 +00:00
if ( s_isElevated )
{
ImGui : : Separator ( ) ;
ImGui : : TextColored ( ImVec4 ( 1 , 0.25f , 0.25f , 1 ) , ICON_FA_TRIANGLE_EXCLAMATION " Profiler has elevated privileges! " ICON_FA_TRIANGLE_EXCLAMATION ) ;
ImGui : : PushFont ( s_smallFont ) ;
ImGui : : TextColored ( ImVec4 ( 1 , 0.25f , 0.25f , 1 ) , " You are running the profiler interface with admin privileges. This is " ) ;
ImGui : : TextColored ( ImVec4 ( 1 , 0.25f , 0.25f , 1 ) , " most likely a mistake, as there is no reason to do so. Instead, you " ) ;
ImGui : : TextColored ( ImVec4 ( 1 , 0.25f , 0.25f , 1 ) , " probably wanted to run the client (the application you are profiling) " ) ;
ImGui : : TextColored ( ImVec4 ( 1 , 0.25f , 0.25f , 1 ) , " with elevated privileges. " ) ;
ImGui : : PopFont ( ) ;
}
2020-01-10 01:10:07 +00:00
ImGui : : Separator ( ) ;
ImGui : : TextUnformatted ( " Client address " ) ;
bool connectClicked = false ;
connectClicked | = ImGui : : InputTextWithHint ( " ###connectaddress " , " Enter address " , addr , 1024 , ImGuiInputTextFlags_EnterReturnsTrue ) ;
2022-07-25 20:57:20 +00:00
if ( ! connHist - > empty ( ) )
2020-01-10 01:10:07 +00:00
{
ImGui : : SameLine ( ) ;
if ( ImGui : : BeginCombo ( " ##frameCombo " , nullptr , ImGuiComboFlags_NoPreview ) )
2018-10-23 17:44:51 +00:00
{
2020-01-10 01:10:07 +00:00
int idxRemove = - 1 ;
2022-07-25 20:57:20 +00:00
const auto sz = std : : min < size_t > ( 5 , connHist - > size ( ) ) ;
2020-01-10 01:10:07 +00:00
for ( size_t i = 0 ; i < sz ; i + + )
2018-10-23 17:44:51 +00:00
{
2022-07-25 20:57:20 +00:00
const auto & str = connHist - > Name ( i ) ;
2020-01-10 01:10:07 +00:00
if ( ImGui : : Selectable ( str . c_str ( ) ) )
2018-10-23 17:44:51 +00:00
{
2020-01-10 01:10:07 +00:00
memcpy ( addr , str . c_str ( ) , str . size ( ) + 1 ) ;
2018-10-23 17:59:11 +00:00
}
2020-01-10 01:10:07 +00:00
if ( ImGui : : IsItemHovered ( ) & & ImGui : : IsKeyPressed ( ImGui : : GetKeyIndex ( ImGuiKey_Delete ) , false ) )
2018-10-23 17:59:11 +00:00
{
2020-01-10 01:10:07 +00:00
idxRemove = ( int ) i ;
2018-10-23 17:44:51 +00:00
}
2018-10-23 17:39:09 +00:00
}
2020-01-10 01:10:07 +00:00
if ( idxRemove > = 0 )
2018-10-23 17:39:09 +00:00
{
2022-07-25 20:57:20 +00:00
connHist - > Erase ( idxRemove ) ;
2018-10-23 17:39:09 +00:00
}
2020-01-10 01:10:07 +00:00
ImGui : : EndCombo ( ) ;
2017-09-15 19:37:28 +00:00
}
2020-01-10 01:10:07 +00:00
}
connectClicked | = ImGui : : Button ( ICON_FA_WIFI " Connect " ) ;
if ( connectClicked & & * addr & & ! loadThread . joinable ( ) )
{
2022-07-25 20:57:20 +00:00
connHist - > Count ( addr ) ;
2018-04-21 12:31:33 +00:00
2022-07-25 20:57:20 +00:00
const auto addrLen = strlen ( addr ) ;
2020-03-08 14:02:20 +00:00
auto ptr = addr + addrLen - 1 ;
while ( ptr > addr & & * ptr ! = ' : ' ) ptr - - ;
if ( * ptr = = ' : ' )
{
std : : string addrPart = std : : string ( addr , ptr ) ;
2020-10-02 16:51:54 +00:00
uint16_t portPart = ( uint16_t ) atoi ( ptr + 1 ) ;
2023-05-01 12:41:38 +00:00
view = std : : make_unique < tracy : : View > ( RunOnMainThread , addrPart . c_str ( ) , portPart , s_fixedWidth , s_smallFont , s_bigFont , SetWindowTitleCallback , SetupScaleCallback , AttentionCallback , s_config ) ;
2020-03-08 14:02:20 +00:00
}
else
{
2023-05-01 12:41:38 +00:00
view = std : : make_unique < tracy : : View > ( RunOnMainThread , addr , port , s_fixedWidth , s_smallFont , s_bigFont , SetWindowTitleCallback , SetupScaleCallback , AttentionCallback , s_config ) ;
2020-03-08 14:02:20 +00:00
}
2020-01-10 01:10:07 +00:00
}
2021-12-22 16:34:04 +00:00
ImGui : : SameLine ( 0 , ImGui : : GetTextLineHeight ( ) * 2 ) ;
2021-03-16 23:51:24 +00:00
# ifndef TRACY_NO_FILESELECTOR
2020-01-10 01:10:07 +00:00
if ( ImGui : : Button ( ICON_FA_FOLDER_OPEN " Open saved trace " ) & & ! loadThread . joinable ( ) )
{
2022-10-06 15:35:07 +00:00
tracy : : Fileselector : : OpenFile ( " tracy " , " Tracy Profiler trace file " , [ ] ( const char * fn ) {
2020-01-10 01:10:07 +00:00
try
2019-06-17 17:45:47 +00:00
{
2022-10-06 15:35:07 +00:00
auto f = std : : shared_ptr < tracy : : FileRead > ( tracy : : FileRead : : Open ( fn ) ) ;
2020-01-10 01:10:07 +00:00
if ( f )
2019-06-18 18:51:12 +00:00
{
2020-01-10 01:10:07 +00:00
loadThread = std : : thread ( [ f ] {
try
{
2023-05-01 12:41:38 +00:00
view = std : : make_unique < tracy : : View > ( RunOnMainThread , * f , s_fixedWidth , s_smallFont , s_bigFont , SetWindowTitleCallback , SetupScaleCallback , AttentionCallback , s_config ) ;
2020-01-10 01:10:07 +00:00
}
catch ( const tracy : : UnsupportedVersion & e )
{
badVer . state = tracy : : BadVersionState : : UnsupportedVersion ;
badVer . version = e . version ;
}
catch ( const tracy : : LegacyVersion & e )
{
badVer . state = tracy : : BadVersionState : : LegacyVersion ;
badVer . version = e . version ;
}
2023-12-31 13:16:06 +00:00
catch ( const tracy : : LoadFailure & e )
{
badVer . state = tracy : : BadVersionState : : LoadFailure ;
badVer . msg = e . msg ;
}
2020-05-03 18:49:13 +00:00
} ) ;
2019-06-17 17:45:47 +00:00
}
}
2020-01-10 01:10:07 +00:00
catch ( const tracy : : NotTracyDump & )
{
badVer . state = tracy : : BadVersionState : : BadFile ;
}
2020-02-12 18:53:37 +00:00
catch ( const tracy : : FileReadError & )
{
badVer . state = tracy : : BadVersionState : : ReadError ;
}
2022-10-06 15:35:07 +00:00
} ) ;
2020-01-10 01:10:07 +00:00
}
2023-12-31 12:54:04 +00:00
# endif
2019-06-17 17:45:47 +00:00
2020-01-10 01:10:07 +00:00
if ( badVer . state ! = tracy : : BadVersionState : : Ok )
{
if ( loadThread . joinable ( ) ) { loadThread . join ( ) ; }
2022-07-24 23:39:13 +00:00
tracy : : BadVersion ( badVer , s_bigFont ) ;
2017-09-15 19:25:47 +00:00
}
2020-01-10 01:10:07 +00:00
if ( ! clients . empty ( ) )
2017-09-15 19:25:47 +00:00
{
2020-01-10 01:10:07 +00:00
ImGui : : Separator ( ) ;
ImGui : : TextUnformatted ( " Discovered clients: " ) ;
2020-05-03 19:10:25 +00:00
ImGui : : SameLine ( ) ;
tracy : : SmallToggleButton ( ICON_FA_FILTER " Filter " , showFilter ) ;
2022-07-25 21:24:59 +00:00
if ( filt - > IsActive ( ) )
2020-05-03 19:10:25 +00:00
{
ImGui : : SameLine ( ) ;
2022-08-17 10:07:38 +00:00
tracy : : TextColoredUnformatted ( 0xFF00FFFF , ICON_FA_TRIANGLE_EXCLAMATION ) ;
2022-01-01 15:57:48 +00:00
tracy : : TooltipIfHovered ( " Filters are active " ) ;
2020-05-03 19:10:25 +00:00
if ( showFilter )
{
ImGui : : SameLine ( ) ;
2022-08-17 10:07:38 +00:00
if ( ImGui : : SmallButton ( ICON_FA_DELETE_LEFT " Clear " ) )
2020-05-03 19:10:25 +00:00
{
2022-07-25 21:24:59 +00:00
filt - > Clear ( ) ;
2020-05-03 19:10:25 +00:00
}
}
}
if ( showFilter )
{
2021-12-22 16:34:04 +00:00
const auto w = ImGui : : GetTextLineHeight ( ) * 12 ;
2020-05-03 19:10:25 +00:00
ImGui : : Separator ( ) ;
2022-07-25 21:24:59 +00:00
filt - > Draw ( w ) ;
2020-05-03 19:10:25 +00:00
}
2020-01-10 01:10:07 +00:00
ImGui : : Separator ( ) ;
static bool widthSet = false ;
ImGui : : Columns ( 3 ) ;
if ( ! widthSet )
2019-06-17 17:34:48 +00:00
{
2020-01-10 01:10:07 +00:00
widthSet = true ;
const auto w = ImGui : : GetWindowWidth ( ) ;
ImGui : : SetColumnWidth ( 0 , w * 0.35f ) ;
ImGui : : SetColumnWidth ( 1 , w * 0.175f ) ;
ImGui : : SetColumnWidth ( 2 , w * 0.425f ) ;
2019-06-17 17:34:48 +00:00
}
2022-09-27 23:31:38 +00:00
const auto time = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( std : : chrono : : system_clock : : now ( ) . time_since_epoch ( ) ) . count ( ) ;
2020-04-05 10:51:40 +00:00
int idx = 0 ;
2020-05-03 19:10:25 +00:00
int passed = 0 ;
2022-09-27 23:31:38 +00:00
std : : lock_guard < std : : mutex > lock ( resolvLock ) ;
2020-01-10 01:10:07 +00:00
for ( auto & v : clients )
2018-04-29 23:16:08 +00:00
{
2020-01-10 01:10:07 +00:00
const bool badProto = v . second . protocolVersion ! = tracy : : ProtocolVersion ;
bool sel = false ;
const auto & name = resolvMap . find ( v . second . address ) ;
assert ( name ! = resolvMap . end ( ) ) ;
2022-07-25 21:24:59 +00:00
if ( filt - > FailAddr ( name - > second . c_str ( ) ) & & filt - > FailAddr ( v . second . address . c_str ( ) ) ) continue ;
if ( filt - > FailPort ( v . second . port ) ) continue ;
if ( filt - > FailProg ( v . second . procName . c_str ( ) ) ) continue ;
2020-01-10 01:10:07 +00:00
ImGuiSelectableFlags flags = ImGuiSelectableFlags_SpanAllColumns ;
if ( badProto ) flags | = ImGuiSelectableFlags_Disabled ;
2020-04-05 10:51:40 +00:00
ImGui : : PushID ( idx + + ) ;
2020-03-08 13:51:28 +00:00
const bool selected = ImGui : : Selectable ( name - > second . c_str ( ) , & sel , flags ) ;
2020-04-05 10:51:40 +00:00
ImGui : : PopID ( ) ;
2021-12-01 16:41:00 +00:00
if ( ImGui : : IsItemHovered ( ImGuiHoveredFlags_AllowWhenDisabled ) )
2020-03-08 15:19:58 +00:00
{
char portstr [ 32 ] ;
2020-10-02 16:51:54 +00:00
sprintf ( portstr , " % " PRIu16 , v . second . port ) ;
2020-03-08 15:19:58 +00:00
ImGui : : BeginTooltip ( ) ;
2020-06-04 00:15:21 +00:00
if ( badProto )
{
tracy : : TextColoredUnformatted ( 0xFF0000FF , " Incompatible protocol! " ) ;
ImGui : : SameLine ( ) ;
2022-07-12 22:53:15 +00:00
auto ph = tracy : : ProtocolHistory ;
2020-06-04 00:15:21 +00:00
ImGui : : TextDisabled ( " (used: %i, required: %i) " , v . second . protocolVersion , tracy : : ProtocolVersion ) ;
2022-07-12 22:53:15 +00:00
while ( ph - > protocol & & ph - > protocol ! = v . second . protocolVersion ) ph + + ;
if ( ph - > protocol )
{
if ( ph - > maxVer )
{
ImGui : : TextDisabled ( " Compatible Tracy versions: %i.%i.%i to %i.%i.%i " , ph - > minVer > > 16 , ( ph - > minVer > > 8 ) & 0xFF , ph - > minVer & 0xFF , ph - > maxVer > > 16 , ( ph - > maxVer > > 8 ) & 0xFF , ph - > maxVer & 0xFF ) ;
}
else
{
ImGui : : TextDisabled ( " Compatible Tracy version: %i.%i.%i " , ph - > minVer > > 16 , ( ph - > minVer > > 8 ) & 0xFF , ph - > minVer & 0xFF ) ;
}
}
ImGui : : Separator ( ) ;
2020-06-04 00:15:21 +00:00
}
2020-03-08 15:19:58 +00:00
tracy : : TextFocused ( " IP: " , v . second . address . c_str ( ) ) ;
tracy : : TextFocused ( " Port: " , portstr ) ;
2022-10-26 21:22:24 +00:00
if ( v . second . pid ! = 0 )
{
tracy : : TextFocused ( " PID: " , tracy : : RealToString ( v . second . pid ) ) ;
}
2020-03-08 15:19:58 +00:00
ImGui : : EndTooltip ( ) ;
}
2020-03-08 13:51:28 +00:00
if ( v . second . port ! = port )
2020-01-10 01:10:07 +00:00
{
2020-03-08 13:51:28 +00:00
ImGui : : SameLine ( ) ;
2020-10-02 16:51:54 +00:00
ImGui : : TextDisabled ( " :% " PRIu16 , v . second . port ) ;
2020-03-08 13:51:28 +00:00
}
if ( selected & & ! loadThread . joinable ( ) )
{
2023-05-01 12:41:38 +00:00
view = std : : make_unique < tracy : : View > ( RunOnMainThread , v . second . address . c_str ( ) , v . second . port , s_fixedWidth , s_smallFont , s_bigFont , SetWindowTitleCallback , SetupScaleCallback , AttentionCallback , s_config ) ;
2020-01-10 01:10:07 +00:00
}
ImGui : : NextColumn ( ) ;
const auto acttime = ( v . second . activeTime + ( time - v . second . time ) / 1000 ) * 1000000000ll ;
if ( badProto )
{
tracy : : TextDisabledUnformatted ( tracy : : TimeToString ( acttime ) ) ;
}
else
{
ImGui : : TextUnformatted ( tracy : : TimeToString ( acttime ) ) ;
}
ImGui : : NextColumn ( ) ;
if ( badProto )
{
tracy : : TextDisabledUnformatted ( v . second . procName . c_str ( ) ) ;
}
else
{
ImGui : : TextUnformatted ( v . second . procName . c_str ( ) ) ;
}
ImGui : : NextColumn ( ) ;
2020-05-03 19:10:25 +00:00
passed + + ;
2018-04-29 23:16:08 +00:00
}
2020-01-10 01:10:07 +00:00
ImGui : : EndColumns ( ) ;
2020-05-03 19:10:25 +00:00
if ( passed = = 0 )
{
ImGui : : TextUnformatted ( " All clients are filtered. " ) ;
}
2017-09-15 19:25:47 +00:00
}
2020-01-10 01:10:07 +00:00
ImGui : : End ( ) ;
2020-09-12 11:22:02 +00:00
if ( showReleaseNotes )
{
assert ( updateNotesThread . joinable ( ) ) ;
2021-11-18 17:57:43 +00:00
ImGui : : SetNextWindowSize ( ImVec2 ( 600 * dpiScale , 400 * dpiScale ) , ImGuiCond_FirstUseEver ) ;
2020-09-12 11:22:02 +00:00
ImGui : : Begin ( " Update available! " , & showReleaseNotes ) ;
if ( ImGui : : Button ( ICON_FA_DOWNLOAD " Download " ) )
{
2021-06-04 12:33:12 +00:00
tracy : : OpenWebpage ( " https://github.com/wolfpld/tracy/releases " ) ;
2020-09-12 11:22:02 +00:00
}
ImGui : : BeginChild ( " ###notes " , ImVec2 ( 0 , 0 ) , true ) ;
if ( releaseNotes . empty ( ) )
{
static float rnTime = 0 ;
rnTime + = ImGui : : GetIO ( ) . DeltaTime ;
tracy : : TextCentered ( " Fetching release notes... " ) ;
tracy : : DrawWaitingDots ( rnTime ) ;
}
else
{
2022-07-24 23:39:13 +00:00
ImGui : : PushFont ( s_fixedWidth ) ;
2020-09-12 11:22:02 +00:00
ImGui : : TextUnformatted ( releaseNotes . c_str ( ) ) ;
ImGui : : PopFont ( ) ;
}
ImGui : : EndChild ( ) ;
ImGui : : End ( ) ;
}
2020-01-10 01:10:07 +00:00
}
else
{
2020-09-12 11:22:02 +00:00
if ( showReleaseNotes ) showReleaseNotes = false ;
2020-01-10 01:10:07 +00:00
if ( broadcastListen )
2018-07-28 16:07:55 +00:00
{
2020-01-10 01:10:07 +00:00
broadcastListen . reset ( ) ;
clients . clear ( ) ;
2018-07-28 16:07:55 +00:00
}
2020-01-10 01:10:07 +00:00
if ( loadThread . joinable ( ) ) loadThread . join ( ) ;
view - > NotifyRootWindowSize ( display_w , display_h ) ;
if ( ! view - > Draw ( ) )
2018-07-28 16:07:55 +00:00
{
2020-05-13 17:20:20 +00:00
viewShutdown . store ( ViewShutdown : : True , std : : memory_order_relaxed ) ;
2020-03-06 21:11:29 +00:00
reconnect = view - > ReconnectRequested ( ) ;
if ( reconnect )
{
reconnectAddr = view - > GetAddress ( ) ;
reconnectPort = view - > GetPort ( ) ;
}
2020-01-10 01:10:07 +00:00
loadThread = std : : thread ( [ view = std : : move ( view ) ] ( ) mutable {
view . reset ( ) ;
2020-05-13 17:20:20 +00:00
viewShutdown . store ( ViewShutdown : : Join , std : : memory_order_relaxed ) ;
2020-01-10 01:10:07 +00:00
} ) ;
}
}
auto & progress = tracy : : Worker : : GetLoadProgress ( ) ;
auto totalProgress = progress . total . load ( std : : memory_order_relaxed ) ;
if ( totalProgress ! = 0 )
{
ImGui : : OpenPopup ( " Loading trace... " ) ;
}
if ( ImGui : : BeginPopupModal ( " Loading trace... " , nullptr , ImGuiWindowFlags_AlwaysAutoResize ) )
{
2022-07-24 23:39:13 +00:00
ImGui : : PushFont ( s_bigFont ) ;
2020-01-10 01:10:07 +00:00
tracy : : TextCentered ( ICON_FA_HOURGLASS_HALF ) ;
2021-11-13 21:16:37 +00:00
ImGui : : PopFont ( ) ;
2019-03-06 01:49:21 +00:00
2020-01-10 01:10:07 +00:00
animTime + = ImGui : : GetIO ( ) . DeltaTime ;
tracy : : DrawWaitingDots ( animTime ) ;
2018-07-28 16:56:52 +00:00
2020-01-10 01:10:07 +00:00
auto currProgress = progress . progress . load ( std : : memory_order_relaxed ) ;
if ( totalProgress = = 0 )
{
ImGui : : CloseCurrentPopup ( ) ;
totalProgress = currProgress ;
2018-07-28 16:07:55 +00:00
}
2020-01-10 01:10:07 +00:00
switch ( currProgress )
2019-07-24 21:54:47 +00:00
{
2020-01-10 01:10:07 +00:00
case tracy : : LoadProgress : : Initialization :
ImGui : : TextUnformatted ( " Initialization... " ) ;
break ;
case tracy : : LoadProgress : : Locks :
ImGui : : TextUnformatted ( " Locks... " ) ;
break ;
case tracy : : LoadProgress : : Messages :
ImGui : : TextUnformatted ( " Messages... " ) ;
break ;
case tracy : : LoadProgress : : Zones :
ImGui : : TextUnformatted ( " CPU zones... " ) ;
2019-07-24 21:54:47 +00:00
break ;
2020-01-10 01:10:07 +00:00
case tracy : : LoadProgress : : GpuZones :
ImGui : : TextUnformatted ( " GPU zones... " ) ;
break ;
case tracy : : LoadProgress : : Plots :
ImGui : : TextUnformatted ( " Plots... " ) ;
break ;
case tracy : : LoadProgress : : Memory :
ImGui : : TextUnformatted ( " Memory... " ) ;
break ;
case tracy : : LoadProgress : : CallStacks :
ImGui : : TextUnformatted ( " Call stacks... " ) ;
break ;
case tracy : : LoadProgress : : FrameImages :
ImGui : : TextUnformatted ( " Frame images... " ) ;
break ;
case tracy : : LoadProgress : : ContextSwitches :
ImGui : : TextUnformatted ( " Context switches... " ) ;
break ;
case tracy : : LoadProgress : : ContextSwitchesPerCpu :
ImGui : : TextUnformatted ( " CPU context switches... " ) ;
2019-07-24 21:54:47 +00:00
break ;
default :
2020-01-10 01:10:07 +00:00
assert ( false ) ;
2019-07-24 21:54:47 +00:00
break ;
}
2020-01-10 01:10:07 +00:00
ImGui : : ProgressBar ( float ( currProgress ) / totalProgress , ImVec2 ( 200 * dpiScale , 0 ) ) ;
ImGui : : TextUnformatted ( " Progress... " ) ;
auto subTotal = progress . subTotal . load ( std : : memory_order_relaxed ) ;
auto subProgress = progress . subProgress . load ( std : : memory_order_relaxed ) ;
if ( subTotal = = 0 )
2019-07-24 21:54:47 +00:00
{
2020-01-10 01:10:07 +00:00
ImGui : : ProgressBar ( 1.f , ImVec2 ( 200 * dpiScale , 0 ) ) ;
2019-07-24 21:54:47 +00:00
}
2020-01-10 01:10:07 +00:00
else
2018-07-29 20:11:24 +00:00
{
2020-01-10 01:10:07 +00:00
ImGui : : ProgressBar ( float ( subProgress ) / subTotal , ImVec2 ( 200 * dpiScale , 0 ) ) ;
2018-07-29 20:11:24 +00:00
}
2020-01-10 01:10:07 +00:00
ImGui : : EndPopup ( ) ;
2017-09-15 19:25:47 +00:00
}
2020-05-13 17:20:20 +00:00
switch ( viewShutdown . load ( std : : memory_order_relaxed ) )
2018-08-31 17:38:19 +00:00
{
2020-01-10 01:10:07 +00:00
case ViewShutdown : : True :
ImGui : : OpenPopup ( " Capture cleanup... " ) ;
break ;
case ViewShutdown : : Join :
loadThread . join ( ) ;
2020-05-13 17:20:20 +00:00
viewShutdown . store ( ViewShutdown : : False , std : : memory_order_relaxed ) ;
2020-03-06 21:11:29 +00:00
if ( reconnect )
{
2023-05-01 12:41:38 +00:00
view = std : : make_unique < tracy : : View > ( RunOnMainThread , reconnectAddr . c_str ( ) , reconnectPort , s_fixedWidth , s_smallFont , s_bigFont , SetWindowTitleCallback , SetupScaleCallback , AttentionCallback , s_config ) ;
2020-03-06 21:11:29 +00:00
}
2020-01-10 01:10:07 +00:00
break ;
default :
break ;
2018-08-31 17:38:19 +00:00
}
2020-01-10 01:10:07 +00:00
if ( ImGui : : BeginPopupModal ( " Capture cleanup... " , nullptr , ImGuiWindowFlags_AlwaysAutoResize ) )
2018-10-23 17:39:09 +00:00
{
2020-05-13 17:20:20 +00:00
if ( viewShutdown . load ( std : : memory_order_relaxed ) ! = ViewShutdown : : True ) ImGui : : CloseCurrentPopup ( ) ;
2022-07-24 23:39:13 +00:00
ImGui : : PushFont ( s_bigFont ) ;
2020-01-10 01:10:07 +00:00
tracy : : TextCentered ( ICON_FA_BROOM ) ;
2021-11-13 21:16:37 +00:00
ImGui : : PopFont ( ) ;
2020-01-10 01:10:07 +00:00
animTime + = ImGui : : GetIO ( ) . DeltaTime ;
tracy : : DrawWaitingDots ( animTime ) ;
2020-09-27 18:56:37 +00:00
ImGui : : TextUnformatted ( " Please wait, cleanup is in progress " ) ;
2020-01-10 01:10:07 +00:00
ImGui : : EndPopup ( ) ;
2018-10-23 17:39:09 +00:00
}
2022-10-29 22:42:45 +00:00
if ( tracy : : Fileselector : : HasFailed ( ) ) ImGui : : OpenPopup ( " File selector is not available " ) ;
if ( ImGui : : BeginPopupModal ( " File selector is not available " , nullptr , ImGuiWindowFlags_AlwaysAutoResize ) )
{
ImGui : : TextUnformatted ( " File selector cannot be displayed. " ) ;
ImGui : : TextUnformatted ( " Check nfd library implementation for details. " ) ;
ImGui : : Separator ( ) ;
if ( ImGui : : Button ( " Ok " ) ) ImGui : : CloseCurrentPopup ( ) ;
ImGui : : EndPopup ( ) ;
}
2022-07-26 22:57:42 +00:00
bptr - > EndFrame ( ) ;
2024-03-15 19:25:00 +00:00
if ( dpiChanged > 0 ) dpiChanged - - ;
2017-09-15 19:25:47 +00:00
}