diff --git a/profiler/build/win32/Tracy.vcxproj b/profiler/build/win32/Tracy.vcxproj
index 49004603..62608eb4 100644
--- a/profiler/build/win32/Tracy.vcxproj
+++ b/profiler/build/win32/Tracy.vcxproj
@@ -117,6 +117,7 @@
+
@@ -171,6 +172,7 @@
+
diff --git a/profiler/build/win32/Tracy.vcxproj.filters b/profiler/build/win32/Tracy.vcxproj.filters
index c199fbb3..09a419d6 100644
--- a/profiler/build/win32/Tracy.vcxproj.filters
+++ b/profiler/build/win32/Tracy.vcxproj.filters
@@ -102,6 +102,9 @@
src
+
+ server
+
@@ -275,6 +278,9 @@
src
+
+ server
+
diff --git a/server/TracyUserData.cpp b/server/TracyUserData.cpp
new file mode 100644
index 00000000..ae187c05
--- /dev/null
+++ b/server/TracyUserData.cpp
@@ -0,0 +1,63 @@
+#include
+#include
+#include
+
+#include "TracyStorage.hpp"
+#include "TracyUserData.hpp"
+
+namespace tracy
+{
+
+constexpr auto FileDescription = "description";
+
+UserData::UserData()
+{
+}
+
+UserData::UserData( const char* program, uint64_t time )
+ : m_program( program )
+ , m_time( time )
+{
+ const auto descpath = GetSavePath( m_program.c_str(), m_time, FileDescription, false );
+ if( descpath )
+ {
+ FILE* f = fopen( descpath, "rb" );
+ if( f )
+ {
+ fseek( f, 0, SEEK_END );
+ const auto sz = ftell( f );
+ fseek( f, 0, SEEK_SET );
+ auto buf = std::make_unique( sz );
+ fread( buf.get(), 1, sz, f );
+ fclose( f );
+ m_description.assign( buf.get(), buf.get() + sz );
+ }
+ }
+}
+
+void UserData::Init( const char* program, uint64_t time )
+{
+ assert( !Valid() );
+ m_program = program;
+ m_time = time;
+}
+
+bool UserData::SetDescription( const char* description )
+{
+ assert( Valid() );
+
+ m_description = description;
+ const auto sz = m_description.size();
+
+ const auto path = GetSavePath( m_program.c_str(), m_time, FileDescription, true );
+ if( !path ) return false;
+
+ FILE* f = fopen( path, "wb" );
+ if( !f ) return false;
+
+ fwrite( description, 1, sz, f );
+ fclose( f );
+ return true;
+}
+
+}
diff --git a/server/TracyUserData.hpp b/server/TracyUserData.hpp
new file mode 100644
index 00000000..4c945a82
--- /dev/null
+++ b/server/TracyUserData.hpp
@@ -0,0 +1,31 @@
+#ifndef __TRACYUSERDATA_HPP__
+#define __TRACYUSERDATA_HPP__
+
+#include
+#include
+
+namespace tracy
+{
+
+class UserData
+{
+public:
+ UserData();
+ UserData( const char* program, uint64_t time );
+
+ bool Valid() const { return !m_program.empty(); }
+ void Init( const char* program, uint64_t time );
+
+ const std::string& GetDescription() const { return m_description; }
+ bool SetDescription( const char* description );
+
+private:
+ std::string m_program;
+ uint64_t m_time;
+
+ std::string m_description;
+};
+
+}
+
+#endif
diff --git a/server/TracyView.cpp b/server/TracyView.cpp
index bddf0733..ea067078 100644
--- a/server/TracyView.cpp
+++ b/server/TracyView.cpp
@@ -109,6 +109,7 @@ View::View( const char* addr, ImFont* fixedWidth, ImFont* bigFont, SetTitleCallb
, m_textEditorFont( fixedWidth )
, m_bigFont( bigFont )
, m_stcb( stcb )
+ , m_userData()
{
assert( s_instance == nullptr );
s_instance = this;
@@ -125,6 +126,7 @@ View::View( FileRead& f, ImFont* fixedWidth, ImFont* bigFont, SetTitleCallback s
, m_textEditorFont( fixedWidth )
, m_bigFont( bigFont )
, m_stcb( stcb )
+ , m_userData( m_worker.GetCaptureProgram().c_str(), m_worker.GetCaptureTime() )
{
assert( s_instance == nullptr );
s_instance = this;
@@ -379,6 +381,7 @@ bool View::DrawImpl()
return !wasCancelled;
}
+ if( !m_userData.Valid() ) m_userData.Init( m_worker.GetCaptureProgram().c_str(), m_worker.GetCaptureTime() );
if( m_saveThreadState.load( std::memory_order_relaxed ) == SaveThreadState::NeedsJoin )
{
m_saveThread.join();
diff --git a/server/TracyView.hpp b/server/TracyView.hpp
index 5da9eff1..09370d22 100644
--- a/server/TracyView.hpp
+++ b/server/TracyView.hpp
@@ -12,6 +12,7 @@
#include "TracyBuzzAnim.hpp"
#include "TracyDecayValue.hpp"
#include "TracyTexture.hpp"
+#include "TracyUserData.hpp"
#include "TracyVector.hpp"
#include "TracyWorker.hpp"
#include "tracy_flat_hash_map.hpp"
@@ -343,6 +344,8 @@ private:
void* m_frameTexture = nullptr;
const void* m_frameTexturePtr = nullptr;
+ UserData m_userData;
+
struct FindZone {
enum : uint64_t { Unselected = std::numeric_limits::max() - 1 };
enum class GroupBy : int { Thread, UserText, Callstack };