diff --git a/profiler/build/win32/Tracy.vcxproj b/profiler/build/win32/Tracy.vcxproj
index ad468652..4fc85265 100644
--- a/profiler/build/win32/Tracy.vcxproj
+++ b/profiler/build/win32/Tracy.vcxproj
@@ -139,12 +139,14 @@
+
+
diff --git a/profiler/build/win32/Tracy.vcxproj.filters b/profiler/build/win32/Tracy.vcxproj.filters
index 44a42acc..a54c40d1 100644
--- a/profiler/build/win32/Tracy.vcxproj.filters
+++ b/profiler/build/win32/Tracy.vcxproj.filters
@@ -291,6 +291,12 @@
server
+
+ server
+
+
+ server
+
diff --git a/server/TracyView.cpp b/server/TracyView.cpp
index b938b617..496ffe7b 100644
--- a/server/TracyView.cpp
+++ b/server/TracyView.cpp
@@ -38,10 +38,6 @@
#include "imgui_internal.h"
-#ifndef TRACY_NO_FILESELECTOR
-# include "../nfd/nfd.h"
-#endif
-
#ifdef _WIN32
# include
#elif defined __linux__
@@ -1237,439 +1233,6 @@ bool View::DrawImpl()
return keepOpen;
}
-void View::DrawNotificationArea()
-{
- auto& io = ImGui::GetIO();
- const auto ty = ImGui::GetTextLineHeight();
- if( m_worker.IsConnected() )
- {
- size_t sqs;
- {
- std::shared_lock lock( m_worker.GetMbpsDataLock() );
- sqs = m_worker.GetSendQueueSize();
- }
- if( sqs != 0 )
- {
- ImGui::SameLine();
- TextColoredUnformatted( ImVec4( 1, 0, 0, 1 ), ICON_FA_SATELLITE_DISH );
- if( ImGui::IsItemHovered() )
- {
- ImGui::BeginTooltip();
- TextFocused( "Query backlog:", RealToString( sqs ) );
- ImGui::EndTooltip();
- }
- }
- else
- {
- const auto sif = m_worker.GetSendInFlight();
- if( sif != 0 )
- {
- ImGui::SameLine();
- TextColoredUnformatted( ImVec4( 1, 0.75f, 0, 1 ), ICON_FA_SATELLITE_DISH );
- if( ImGui::IsItemHovered() )
- {
- ImGui::BeginTooltip();
- TextFocused( "Queries in flight:", RealToString( sif ) );
- ImGui::EndTooltip();
- }
- }
- }
- }
- auto& crash = m_worker.GetCrashEvent();
- if( crash.thread != 0 )
- {
- ImGui::SameLine();
- TextColoredUnformatted( ImVec4( 1, 0, 0, 1 ), ICON_FA_SKULL );
- if( ImGui::IsItemHovered() )
- {
- CrashTooltip();
- if( IsMouseClicked( 0 ) )
- {
- m_showInfo = true;
- }
- if( IsMouseClicked( 2 ) )
- {
- CenterAtTime( crash.time );
- }
- }
- }
- if( m_worker.AreSamplesInconsistent() )
- {
- ImGui::SameLine();
- TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_EYE_DROPPER );
- TooltipIfHovered( "Sampling data and ghost zones may be displayed wrongly due to data inconsistency. Save and reload the trace to fix this." );
- }
- if( m_vd.drawEmptyLabels )
- {
- ImGui::SameLine();
- TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_EXPAND );
- if( ImGui::IsItemHovered() )
- {
- ImGui::BeginTooltip();
- ImGui::TextUnformatted( "Displaying empty labels." );
- ImGui::EndTooltip();
- if( IsMouseClicked( 0 ) ) m_vd.drawEmptyLabels = false;
- }
- }
- if( !m_vd.drawContextSwitches )
- {
- ImGui::SameLine();
- TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_HIKING );
- if( ImGui::IsItemHovered() )
- {
- ImGui::BeginTooltip();
- ImGui::TextUnformatted( "Context switches are hidden." );
- ImGui::EndTooltip();
- if( IsMouseClicked( 0 ) ) m_vd.drawContextSwitches = true;
- }
- }
- if( !m_vd.drawCpuData )
- {
- ImGui::SameLine();
- TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_SLIDERS_H );
- if( ImGui::IsItemHovered() )
- {
- ImGui::BeginTooltip();
- ImGui::TextUnformatted( "CPU data is hidden." );
- ImGui::EndTooltip();
- if( IsMouseClicked( 0 ) ) m_vd.drawCpuData = true;
- }
- }
- if( !m_vd.drawGpuZones )
- {
- ImGui::SameLine();
- TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_EYE );
- if( ImGui::IsItemHovered() )
- {
- ImGui::BeginTooltip();
- ImGui::TextUnformatted( "GPU zones are hidden." );
- ImGui::EndTooltip();
- if( IsMouseClicked( 0 ) ) m_vd.drawGpuZones = true;
- }
- }
- if( !m_vd.drawZones )
- {
- ImGui::SameLine();
- TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_MICROCHIP );
- if( ImGui::IsItemHovered() )
- {
- ImGui::BeginTooltip();
- ImGui::TextUnformatted( "CPU zones are hidden." );
- ImGui::EndTooltip();
- if( IsMouseClicked( 0 ) ) m_vd.drawZones = true;
- }
- }
-#ifndef TRACY_NO_STATISTICS
- if( !m_vd.ghostZones )
- {
- ImGui::SameLine();
- TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_GHOST );
- if( ImGui::IsItemHovered() )
- {
- ImGui::BeginTooltip();
- ImGui::TextUnformatted( "Ghost zones are hidden." );
- ImGui::EndTooltip();
- if( IsMouseClicked( 0 ) ) m_vd.ghostZones = true;
- }
- }
-#endif
- if( !m_vd.drawLocks )
- {
- ImGui::SameLine();
- TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_LOCK );
- if( ImGui::IsItemHovered() )
- {
- ImGui::BeginTooltip();
- ImGui::TextUnformatted( "Locks are hidden." );
- ImGui::EndTooltip();
- if( IsMouseClicked( 0 ) ) m_vd.drawLocks = true;
- }
- }
- if( !m_vd.drawPlots )
- {
- ImGui::SameLine();
- TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_SIGNATURE );
- if( ImGui::IsItemHovered() )
- {
- ImGui::BeginTooltip();
- ImGui::TextUnformatted( "Plots are hidden." );
- ImGui::EndTooltip();
- if( IsMouseClicked( 0 ) ) m_vd.drawPlots = true;
- }
- }
- {
- bool hidden = false;
- for( auto& v : m_visData )
- {
- if( !v.second.visible )
- {
- hidden = true;
- break;
- }
- }
- if( hidden )
- {
- ImGui::SameLine();
- TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_LOW_VISION );
- if( ImGui::IsItemHovered() )
- {
- ImGui::BeginTooltip();
- ImGui::TextUnformatted( "Some timeline entries are hidden." );
- ImGui::EndTooltip();
- if( IsMouseClicked( 0 ) ) m_showOptions = true;
- }
- }
- }
- if( !m_worker.IsBackgroundDone() )
- {
- ImGui::SameLine();
- TextDisabledUnformatted( ICON_FA_TASKS );
- ImGui::SameLine();
- const auto pos = ImGui::GetCursorPos();
- ImGui::TextUnformatted( " " );
- ImGui::GetWindowDrawList()->AddCircleFilled( pos + ImVec2( 0, ty * 0.75f ), ty * ( 0.2f + ( sin( s_time * 8 ) + 1 ) * 0.125f ), 0xFF888888, 10 );
- auto rmin = ImGui::GetItemRectMin();
- rmin.x -= ty * 0.5f;
- const auto rmax = ImGui::GetItemRectMax();
- if( ImGui::IsMouseHoveringRect( rmin, rmax ) )
- {
- ImGui::BeginTooltip();
- ImGui::TextUnformatted( "Processing background tasks" );
- ImGui::EndTooltip();
- }
- }
- if( m_saveThreadState.load( std::memory_order_relaxed ) == SaveThreadState::Saving )
- {
- ImGui::SameLine();
- ImGui::TextUnformatted( ICON_FA_SAVE " Saving trace..." );
- m_notificationTime = 0;
- }
- else if( m_notificationTime > 0 )
- {
- m_notificationTime -= std::min( io.DeltaTime, 0.25f );
- ImGui::SameLine();
- TextDisabledUnformatted( m_notificationText.c_str() );
- }
-
- ImGui::PushFont( m_smallFont );
- const auto wpos = ImGui::GetWindowPos();
- const auto w = ImGui::GetContentRegionAvail().x;
- const auto fps = RealToString( int( io.Framerate + 0.5f ) );
- const auto fpssz = ImGui::CalcTextSize( fps ).x;
- ImGui::GetWindowDrawList()->AddText( wpos + ImVec2( w-fpssz, 0 ), 0x88FFFFFF, fps );
- ImGui::PopFont();
-}
-
-bool View::DrawConnection()
-{
- const auto scale = GetScale();
- const auto ty = ImGui::GetTextLineHeight();
- const auto cs = ty * 0.9f;
- const auto isConnected = m_worker.IsConnected();
-
- {
- std::shared_lock lock( m_worker.GetMbpsDataLock() );
- TextFocused( isConnected ? "Connected to:" : "Disconnected:", m_worker.GetAddr().c_str() );
- const auto& mbpsVector = m_worker.GetMbpsData();
- const auto mbps = mbpsVector.back();
- char buf[64];
- if( mbps < 0.1f )
- {
- sprintf( buf, "%6.2f Kbps", mbps * 1000.f );
- }
- else
- {
- sprintf( buf, "%6.2f Mbps", mbps );
- }
- ImGui::Dummy( ImVec2( cs, 0 ) );
- ImGui::SameLine();
- ImGui::PlotLines( buf, mbpsVector.data(), mbpsVector.size(), 0, nullptr, 0, std::numeric_limits::max(), ImVec2( 150 * scale, 0 ) );
- TextDisabledUnformatted( "Ratio" );
- ImGui::SameLine();
- ImGui::Text( "%.1f%%", m_worker.GetCompRatio() * 100.f );
- ImGui::SameLine();
- TextDisabledUnformatted( "Real:" );
- ImGui::SameLine();
- ImGui::Text( "%6.2f Mbps", mbps / m_worker.GetCompRatio() );
- TextFocused( "Data transferred:", MemSizeToString( m_worker.GetDataTransferred() ) );
- TextFocused( "Query backlog:", RealToString( m_worker.GetSendQueueSize() ) );
- }
-
- const auto wpos = ImGui::GetWindowPos() + ImGui::GetWindowContentRegionMin();
- ImGui::GetWindowDrawList()->AddCircleFilled( wpos + ImVec2( 1 + cs * 0.5, 3 + ty * 1.75 ), cs * 0.5, isConnected ? 0xFF2222CC : 0xFF444444, 10 );
-
- {
- std::lock_guard lock( m_worker.GetDataLock() );
- ImGui::SameLine();
- TextFocused( "+", RealToString( m_worker.GetSendInFlight() ) );
- const auto sz = m_worker.GetFrameCount( *m_frames );
- if( sz > 1 )
- {
- const auto dt = m_worker.GetFrameTime( *m_frames, sz - 2 );
- const auto fps = 1000000000.f / dt;
- TextDisabledUnformatted( "FPS:" );
- ImGui::SameLine();
- ImGui::Text( "%6.1f", fps );
- ImGui::SameLine();
- TextFocused( "Frame time:", TimeToString( dt ) );
- }
- }
-
- const auto& fis = m_worker.GetFrameImages();
- if( !fis.empty() )
- {
- const auto fiScale = scale * 0.5f;
- const auto& fi = fis.back();
- if( fi != m_frameTextureConnPtr )
- {
- if( !m_frameTextureConn ) m_frameTextureConn = MakeTexture();
- UpdateTexture( m_frameTextureConn, m_worker.UnpackFrameImage( *fi ), fi->w, fi->h );
- m_frameTextureConnPtr = fi;
- }
- ImGui::Separator();
- if( fi->flip )
- {
- ImGui::Image( m_frameTextureConn, ImVec2( fi->w * fiScale, fi->h * fiScale ), ImVec2( 0, 1 ), ImVec2( 1, 0 ) );
- }
- else
- {
- ImGui::Image( m_frameTextureConn, ImVec2( fi->w * fiScale, fi->h * fiScale ) );
- }
- }
-
- ImGui::Separator();
- if( ImGui::Button( ICON_FA_SAVE " Save trace" ) && m_saveThreadState.load( std::memory_order_relaxed ) == SaveThreadState::Inert )
- {
-#ifndef TRACY_NO_FILESELECTOR
- nfdu8filteritem_t filter = { "Tracy Profiler trace file", "tracy" };
- nfdu8char_t* fn;
- auto res = NFD_SaveDialogU8( &fn, &filter, 1, nullptr, nullptr );
- if( res == NFD_OKAY )
-#else
- const char* fn = "trace.tracy";
-#endif
- {
- const auto sz = strlen( fn );
- if( sz < 7 || memcmp( fn + sz - 6, ".tracy", 6 ) != 0 )
- {
- char tmp[1024];
- sprintf( tmp, "%s.tracy", fn );
- m_filenameStaging = tmp;
- }
- else
- {
- m_filenameStaging = fn;
- }
-#ifndef TRACY_NO_FILESELECTOR
- NFD_FreePathU8( fn );
-#endif
- }
- }
-
- ImGui::SameLine( 0, 2 * ty );
- const char* stopStr = ICON_FA_PLUG " Stop";
- std::lock_guard lock( m_worker.GetDataLock() );
- if( !m_disconnectIssued && m_worker.IsConnected() )
- {
- if( ImGui::Button( stopStr ) )
- {
- m_worker.Disconnect();
- m_disconnectIssued = true;
- }
- }
- else
- {
- ImGui::BeginDisabled();
- ImGui::Button( stopStr );
- ImGui::EndDisabled();
- }
-
- ImGui::SameLine();
- if( ImGui::Button( ICON_FA_EXCLAMATION_TRIANGLE " Discard" ) )
- {
- ImGui::OpenPopup( "Confirm trace discard" );
- }
-
- if( ImGui::BeginPopupModal( "Confirm trace discard", nullptr, ImGuiWindowFlags_AlwaysAutoResize ) )
- {
- ImGui::PushFont( m_bigFont );
- TextCentered( ICON_FA_EXCLAMATION_TRIANGLE );
- ImGui::PopFont();
- ImGui::TextUnformatted( "All unsaved profiling data will be lost!" );
- ImGui::TextUnformatted( "Are you sure you want to proceed?" );
- ImGui::Separator();
- if( ImGui::Button( "Yes" ) )
- {
- ImGui::CloseCurrentPopup();
- ImGui::EndPopup();
- return false;
- }
- ImGui::SameLine();
- if( ImGui::Button( "Reconnect" ) )
- {
- ImGui::CloseCurrentPopup();
- ImGui::EndPopup();
- m_reconnectRequested = true;
- return false;
- }
- ImGui::SameLine( 0, ty * 2 );
- if( ImGui::Button( "No", ImVec2( ty * 6, 0 ) ) )
- {
- ImGui::CloseCurrentPopup();
- }
- ImGui::EndPopup();
- }
-
- if( m_worker.IsConnected() )
- {
- const auto& params = m_worker.GetParameters();
- if( !params.empty() )
- {
- ImGui::Separator();
- if( ImGui::TreeNode( "Trace parameters" ) )
- {
- if( ImGui::BeginTable( "##traceparams", 2, ImGuiTableFlags_Borders ) )
- {
- ImGui::TableSetupColumn( "Name" );
- ImGui::TableSetupColumn( "Value", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize );
- ImGui::TableHeadersRow();
- size_t idx = 0;
- for( auto& p : params )
- {
- ImGui::TableNextRow();
- ImGui::TableNextColumn();
- ImGui::TextUnformatted( m_worker.GetString( p.name ) );
- ImGui::TableNextColumn();
- ImGui::PushID( idx );
- if( p.isBool )
- {
- bool val = p.val;
- if( ImGui::Checkbox( "", &val ) )
- {
- m_worker.SetParameter( idx, int32_t( val ) );
- }
- }
- else
- {
- auto val = int( p.val );
- if( ImGui::InputInt( "", &val, 1, 100, ImGuiInputTextFlags_EnterReturnsTrue ) )
- {
- m_worker.SetParameter( idx, int32_t( val ) );
- }
- }
- ImGui::PopID();
- idx++;
- }
- ImGui::EndTable();
- }
- ImGui::TreePop();
- }
- }
- }
-
- return true;
-}
-
void View::HandleRange( Range& range, int64_t timespan, const ImVec2& wpos, float w )
{
if( !IsMouseDown( 0 ) ) range.modMin = range.modMax = false;
diff --git a/server/TracyView_Compare.cpp b/server/TracyView_Compare.cpp
index 3aa566b1..4fed77ea 100644
--- a/server/TracyView_Compare.cpp
+++ b/server/TracyView_Compare.cpp
@@ -1,4 +1,6 @@
-#include "../nfd/nfd.h"
+#ifndef TRACY_NO_FILESELECTOR
+# include "../nfd/nfd.h"
+#endif
#include "TracyFileRead.hpp"
#include "TracyPrint.hpp"
diff --git a/server/TracyView_ConnectionState.cpp b/server/TracyView_ConnectionState.cpp
new file mode 100644
index 00000000..5b7d0f88
--- /dev/null
+++ b/server/TracyView_ConnectionState.cpp
@@ -0,0 +1,221 @@
+#ifndef TRACY_NO_FILESELECTOR
+# include "../nfd/nfd.h"
+#endif
+
+#include "TracyPrint.hpp"
+#include "TracyView.hpp"
+
+namespace tracy
+{
+
+bool View::DrawConnection()
+{
+ const auto scale = GetScale();
+ const auto ty = ImGui::GetTextLineHeight();
+ const auto cs = ty * 0.9f;
+ const auto isConnected = m_worker.IsConnected();
+
+ {
+ std::shared_lock lock( m_worker.GetMbpsDataLock() );
+ TextFocused( isConnected ? "Connected to:" : "Disconnected:", m_worker.GetAddr().c_str() );
+ const auto& mbpsVector = m_worker.GetMbpsData();
+ const auto mbps = mbpsVector.back();
+ char buf[64];
+ if( mbps < 0.1f )
+ {
+ sprintf( buf, "%6.2f Kbps", mbps * 1000.f );
+ }
+ else
+ {
+ sprintf( buf, "%6.2f Mbps", mbps );
+ }
+ ImGui::Dummy( ImVec2( cs, 0 ) );
+ ImGui::SameLine();
+ ImGui::PlotLines( buf, mbpsVector.data(), mbpsVector.size(), 0, nullptr, 0, std::numeric_limits::max(), ImVec2( 150 * scale, 0 ) );
+ TextDisabledUnformatted( "Ratio" );
+ ImGui::SameLine();
+ ImGui::Text( "%.1f%%", m_worker.GetCompRatio() * 100.f );
+ ImGui::SameLine();
+ TextDisabledUnformatted( "Real:" );
+ ImGui::SameLine();
+ ImGui::Text( "%6.2f Mbps", mbps / m_worker.GetCompRatio() );
+ TextFocused( "Data transferred:", MemSizeToString( m_worker.GetDataTransferred() ) );
+ TextFocused( "Query backlog:", RealToString( m_worker.GetSendQueueSize() ) );
+ }
+
+ const auto wpos = ImGui::GetWindowPos() + ImGui::GetWindowContentRegionMin();
+ ImGui::GetWindowDrawList()->AddCircleFilled( wpos + ImVec2( 1 + cs * 0.5, 3 + ty * 1.75 ), cs * 0.5, isConnected ? 0xFF2222CC : 0xFF444444, 10 );
+
+ {
+ std::lock_guard lock( m_worker.GetDataLock() );
+ ImGui::SameLine();
+ TextFocused( "+", RealToString( m_worker.GetSendInFlight() ) );
+ const auto sz = m_worker.GetFrameCount( *m_frames );
+ if( sz > 1 )
+ {
+ const auto dt = m_worker.GetFrameTime( *m_frames, sz - 2 );
+ const auto fps = 1000000000.f / dt;
+ TextDisabledUnformatted( "FPS:" );
+ ImGui::SameLine();
+ ImGui::Text( "%6.1f", fps );
+ ImGui::SameLine();
+ TextFocused( "Frame time:", TimeToString( dt ) );
+ }
+ }
+
+ const auto& fis = m_worker.GetFrameImages();
+ if( !fis.empty() )
+ {
+ const auto fiScale = scale * 0.5f;
+ const auto& fi = fis.back();
+ if( fi != m_frameTextureConnPtr )
+ {
+ if( !m_frameTextureConn ) m_frameTextureConn = MakeTexture();
+ UpdateTexture( m_frameTextureConn, m_worker.UnpackFrameImage( *fi ), fi->w, fi->h );
+ m_frameTextureConnPtr = fi;
+ }
+ ImGui::Separator();
+ if( fi->flip )
+ {
+ ImGui::Image( m_frameTextureConn, ImVec2( fi->w * fiScale, fi->h * fiScale ), ImVec2( 0, 1 ), ImVec2( 1, 0 ) );
+ }
+ else
+ {
+ ImGui::Image( m_frameTextureConn, ImVec2( fi->w * fiScale, fi->h * fiScale ) );
+ }
+ }
+
+ ImGui::Separator();
+ if( ImGui::Button( ICON_FA_SAVE " Save trace" ) && m_saveThreadState.load( std::memory_order_relaxed ) == SaveThreadState::Inert )
+ {
+#ifndef TRACY_NO_FILESELECTOR
+ nfdu8filteritem_t filter = { "Tracy Profiler trace file", "tracy" };
+ nfdu8char_t* fn;
+ auto res = NFD_SaveDialogU8( &fn, &filter, 1, nullptr, nullptr );
+ if( res == NFD_OKAY )
+#else
+ const char* fn = "trace.tracy";
+#endif
+ {
+ const auto sz = strlen( fn );
+ if( sz < 7 || memcmp( fn + sz - 6, ".tracy", 6 ) != 0 )
+ {
+ char tmp[1024];
+ sprintf( tmp, "%s.tracy", fn );
+ m_filenameStaging = tmp;
+ }
+ else
+ {
+ m_filenameStaging = fn;
+ }
+#ifndef TRACY_NO_FILESELECTOR
+ NFD_FreePathU8( fn );
+#endif
+ }
+ }
+
+ ImGui::SameLine( 0, 2 * ty );
+ const char* stopStr = ICON_FA_PLUG " Stop";
+ std::lock_guard lock( m_worker.GetDataLock() );
+ if( !m_disconnectIssued && m_worker.IsConnected() )
+ {
+ if( ImGui::Button( stopStr ) )
+ {
+ m_worker.Disconnect();
+ m_disconnectIssued = true;
+ }
+ }
+ else
+ {
+ ImGui::BeginDisabled();
+ ImGui::Button( stopStr );
+ ImGui::EndDisabled();
+ }
+
+ ImGui::SameLine();
+ if( ImGui::Button( ICON_FA_EXCLAMATION_TRIANGLE " Discard" ) )
+ {
+ ImGui::OpenPopup( "Confirm trace discard" );
+ }
+
+ if( ImGui::BeginPopupModal( "Confirm trace discard", nullptr, ImGuiWindowFlags_AlwaysAutoResize ) )
+ {
+ ImGui::PushFont( m_bigFont );
+ TextCentered( ICON_FA_EXCLAMATION_TRIANGLE );
+ ImGui::PopFont();
+ ImGui::TextUnformatted( "All unsaved profiling data will be lost!" );
+ ImGui::TextUnformatted( "Are you sure you want to proceed?" );
+ ImGui::Separator();
+ if( ImGui::Button( "Yes" ) )
+ {
+ ImGui::CloseCurrentPopup();
+ ImGui::EndPopup();
+ return false;
+ }
+ ImGui::SameLine();
+ if( ImGui::Button( "Reconnect" ) )
+ {
+ ImGui::CloseCurrentPopup();
+ ImGui::EndPopup();
+ m_reconnectRequested = true;
+ return false;
+ }
+ ImGui::SameLine( 0, ty * 2 );
+ if( ImGui::Button( "No", ImVec2( ty * 6, 0 ) ) )
+ {
+ ImGui::CloseCurrentPopup();
+ }
+ ImGui::EndPopup();
+ }
+
+ if( m_worker.IsConnected() )
+ {
+ const auto& params = m_worker.GetParameters();
+ if( !params.empty() )
+ {
+ ImGui::Separator();
+ if( ImGui::TreeNode( "Trace parameters" ) )
+ {
+ if( ImGui::BeginTable( "##traceparams", 2, ImGuiTableFlags_Borders ) )
+ {
+ ImGui::TableSetupColumn( "Name" );
+ ImGui::TableSetupColumn( "Value", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize );
+ ImGui::TableHeadersRow();
+ size_t idx = 0;
+ for( auto& p : params )
+ {
+ ImGui::TableNextRow();
+ ImGui::TableNextColumn();
+ ImGui::TextUnformatted( m_worker.GetString( p.name ) );
+ ImGui::TableNextColumn();
+ ImGui::PushID( idx );
+ if( p.isBool )
+ {
+ bool val = p.val;
+ if( ImGui::Checkbox( "", &val ) )
+ {
+ m_worker.SetParameter( idx, int32_t( val ) );
+ }
+ }
+ else
+ {
+ auto val = int( p.val );
+ if( ImGui::InputInt( "", &val, 1, 100, ImGuiInputTextFlags_EnterReturnsTrue ) )
+ {
+ m_worker.SetParameter( idx, int32_t( val ) );
+ }
+ }
+ ImGui::PopID();
+ idx++;
+ }
+ ImGui::EndTable();
+ }
+ ImGui::TreePop();
+ }
+ }
+ }
+
+ return true;
+}
+
+}
diff --git a/server/TracyView_NotificationArea.cpp b/server/TracyView_NotificationArea.cpp
new file mode 100644
index 00000000..6f5b7356
--- /dev/null
+++ b/server/TracyView_NotificationArea.cpp
@@ -0,0 +1,233 @@
+#include "TracyMouse.hpp"
+#include "TracyPrint.hpp"
+#include "TracyView.hpp"
+
+namespace tracy
+{
+
+extern double s_time;
+
+void View::DrawNotificationArea()
+{
+ auto& io = ImGui::GetIO();
+ const auto ty = ImGui::GetTextLineHeight();
+ if( m_worker.IsConnected() )
+ {
+ size_t sqs;
+ {
+ std::shared_lock lock( m_worker.GetMbpsDataLock() );
+ sqs = m_worker.GetSendQueueSize();
+ }
+ if( sqs != 0 )
+ {
+ ImGui::SameLine();
+ TextColoredUnformatted( ImVec4( 1, 0, 0, 1 ), ICON_FA_SATELLITE_DISH );
+ if( ImGui::IsItemHovered() )
+ {
+ ImGui::BeginTooltip();
+ TextFocused( "Query backlog:", RealToString( sqs ) );
+ ImGui::EndTooltip();
+ }
+ }
+ else
+ {
+ const auto sif = m_worker.GetSendInFlight();
+ if( sif != 0 )
+ {
+ ImGui::SameLine();
+ TextColoredUnformatted( ImVec4( 1, 0.75f, 0, 1 ), ICON_FA_SATELLITE_DISH );
+ if( ImGui::IsItemHovered() )
+ {
+ ImGui::BeginTooltip();
+ TextFocused( "Queries in flight:", RealToString( sif ) );
+ ImGui::EndTooltip();
+ }
+ }
+ }
+ }
+ auto& crash = m_worker.GetCrashEvent();
+ if( crash.thread != 0 )
+ {
+ ImGui::SameLine();
+ TextColoredUnformatted( ImVec4( 1, 0, 0, 1 ), ICON_FA_SKULL );
+ if( ImGui::IsItemHovered() )
+ {
+ CrashTooltip();
+ if( IsMouseClicked( 0 ) )
+ {
+ m_showInfo = true;
+ }
+ if( IsMouseClicked( 2 ) )
+ {
+ CenterAtTime( crash.time );
+ }
+ }
+ }
+ if( m_worker.AreSamplesInconsistent() )
+ {
+ ImGui::SameLine();
+ TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_EYE_DROPPER );
+ TooltipIfHovered( "Sampling data and ghost zones may be displayed wrongly due to data inconsistency. Save and reload the trace to fix this." );
+ }
+ if( m_vd.drawEmptyLabels )
+ {
+ ImGui::SameLine();
+ TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_EXPAND );
+ if( ImGui::IsItemHovered() )
+ {
+ ImGui::BeginTooltip();
+ ImGui::TextUnformatted( "Displaying empty labels." );
+ ImGui::EndTooltip();
+ if( IsMouseClicked( 0 ) ) m_vd.drawEmptyLabels = false;
+ }
+ }
+ if( !m_vd.drawContextSwitches )
+ {
+ ImGui::SameLine();
+ TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_HIKING );
+ if( ImGui::IsItemHovered() )
+ {
+ ImGui::BeginTooltip();
+ ImGui::TextUnformatted( "Context switches are hidden." );
+ ImGui::EndTooltip();
+ if( IsMouseClicked( 0 ) ) m_vd.drawContextSwitches = true;
+ }
+ }
+ if( !m_vd.drawCpuData )
+ {
+ ImGui::SameLine();
+ TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_SLIDERS_H );
+ if( ImGui::IsItemHovered() )
+ {
+ ImGui::BeginTooltip();
+ ImGui::TextUnformatted( "CPU data is hidden." );
+ ImGui::EndTooltip();
+ if( IsMouseClicked( 0 ) ) m_vd.drawCpuData = true;
+ }
+ }
+ if( !m_vd.drawGpuZones )
+ {
+ ImGui::SameLine();
+ TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_EYE );
+ if( ImGui::IsItemHovered() )
+ {
+ ImGui::BeginTooltip();
+ ImGui::TextUnformatted( "GPU zones are hidden." );
+ ImGui::EndTooltip();
+ if( IsMouseClicked( 0 ) ) m_vd.drawGpuZones = true;
+ }
+ }
+ if( !m_vd.drawZones )
+ {
+ ImGui::SameLine();
+ TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_MICROCHIP );
+ if( ImGui::IsItemHovered() )
+ {
+ ImGui::BeginTooltip();
+ ImGui::TextUnformatted( "CPU zones are hidden." );
+ ImGui::EndTooltip();
+ if( IsMouseClicked( 0 ) ) m_vd.drawZones = true;
+ }
+ }
+#ifndef TRACY_NO_STATISTICS
+ if( !m_vd.ghostZones )
+ {
+ ImGui::SameLine();
+ TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_GHOST );
+ if( ImGui::IsItemHovered() )
+ {
+ ImGui::BeginTooltip();
+ ImGui::TextUnformatted( "Ghost zones are hidden." );
+ ImGui::EndTooltip();
+ if( IsMouseClicked( 0 ) ) m_vd.ghostZones = true;
+ }
+ }
+#endif
+ if( !m_vd.drawLocks )
+ {
+ ImGui::SameLine();
+ TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_LOCK );
+ if( ImGui::IsItemHovered() )
+ {
+ ImGui::BeginTooltip();
+ ImGui::TextUnformatted( "Locks are hidden." );
+ ImGui::EndTooltip();
+ if( IsMouseClicked( 0 ) ) m_vd.drawLocks = true;
+ }
+ }
+ if( !m_vd.drawPlots )
+ {
+ ImGui::SameLine();
+ TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_SIGNATURE );
+ if( ImGui::IsItemHovered() )
+ {
+ ImGui::BeginTooltip();
+ ImGui::TextUnformatted( "Plots are hidden." );
+ ImGui::EndTooltip();
+ if( IsMouseClicked( 0 ) ) m_vd.drawPlots = true;
+ }
+ }
+ {
+ bool hidden = false;
+ for( auto& v : m_visData )
+ {
+ if( !v.second.visible )
+ {
+ hidden = true;
+ break;
+ }
+ }
+ if( hidden )
+ {
+ ImGui::SameLine();
+ TextColoredUnformatted( ImVec4( 1, 0.5, 0, 1 ), ICON_FA_LOW_VISION );
+ if( ImGui::IsItemHovered() )
+ {
+ ImGui::BeginTooltip();
+ ImGui::TextUnformatted( "Some timeline entries are hidden." );
+ ImGui::EndTooltip();
+ if( IsMouseClicked( 0 ) ) m_showOptions = true;
+ }
+ }
+ }
+ if( !m_worker.IsBackgroundDone() )
+ {
+ ImGui::SameLine();
+ TextDisabledUnformatted( ICON_FA_TASKS );
+ ImGui::SameLine();
+ const auto pos = ImGui::GetCursorPos();
+ ImGui::TextUnformatted( " " );
+ ImGui::GetWindowDrawList()->AddCircleFilled( pos + ImVec2( 0, ty * 0.75f ), ty * ( 0.2f + ( sin( s_time * 8 ) + 1 ) * 0.125f ), 0xFF888888, 10 );
+ auto rmin = ImGui::GetItemRectMin();
+ rmin.x -= ty * 0.5f;
+ const auto rmax = ImGui::GetItemRectMax();
+ if( ImGui::IsMouseHoveringRect( rmin, rmax ) )
+ {
+ ImGui::BeginTooltip();
+ ImGui::TextUnformatted( "Processing background tasks" );
+ ImGui::EndTooltip();
+ }
+ }
+ if( m_saveThreadState.load( std::memory_order_relaxed ) == SaveThreadState::Saving )
+ {
+ ImGui::SameLine();
+ ImGui::TextUnformatted( ICON_FA_SAVE " Saving trace..." );
+ m_notificationTime = 0;
+ }
+ else if( m_notificationTime > 0 )
+ {
+ m_notificationTime -= std::min( io.DeltaTime, 0.25f );
+ ImGui::SameLine();
+ TextDisabledUnformatted( m_notificationText.c_str() );
+ }
+
+ ImGui::PushFont( m_smallFont );
+ const auto wpos = ImGui::GetWindowPos();
+ const auto w = ImGui::GetContentRegionAvail().x;
+ const auto fps = RealToString( int( io.Framerate + 0.5f ) );
+ const auto fpssz = ImGui::CalcTextSize( fps ).x;
+ ImGui::GetWindowDrawList()->AddText( wpos + ImVec2( w-fpssz, 0 ), 0x88FFFFFF, fps );
+ ImGui::PopFont();
+}
+
+}