tracy/server/TracyUserData.cpp

350 lines
11 KiB
C++
Raw Normal View History

2019-07-26 21:05:24 +00:00
#include <assert.h>
#include <memory>
2019-10-13 15:13:15 +00:00
#ifdef _WIN32
# include <stdio.h>
#else
# include <unistd.h>
#endif
2019-07-26 21:05:24 +00:00
#include "TracyStorage.hpp"
#include "TracyUserData.hpp"
2019-08-28 17:45:22 +00:00
#include "TracyViewData.hpp"
2019-07-26 21:05:24 +00:00
namespace tracy
{
constexpr auto FileDescription = "description";
2019-08-28 17:45:22 +00:00
constexpr auto FileTimeline = "timeline";
2019-08-28 19:35:08 +00:00
constexpr auto FileOptions = "options";
2019-10-13 14:29:24 +00:00
constexpr auto FileAnnotations = "annotations";
2020-04-18 12:25:04 +00:00
constexpr auto FileSourceSubstitutions = "srcsub";
2019-08-28 17:45:22 +00:00
enum : uint32_t { VersionTimeline = 0 };
2020-11-15 14:46:23 +00:00
enum : uint32_t { VersionOptions = 7 };
2019-10-13 14:29:24 +00:00
enum : uint32_t { VersionAnnotations = 0 };
2020-04-18 12:25:04 +00:00
enum : uint32_t { VersionSourceSubstitutions = 0 };
2019-07-26 21:05:24 +00:00
UserData::UserData()
: m_preserveState( false )
2019-07-26 21:05:24 +00:00
{
}
UserData::UserData( const char* program, uint64_t time )
: m_program( program )
, m_time( time )
{
2019-08-28 17:28:31 +00:00
FILE* f = OpenFile( FileDescription, false );
if( f )
2019-07-26 21:05:24 +00:00
{
2019-08-28 17:28:31 +00:00
fseek( f, 0, SEEK_END );
const auto sz = ftell( f );
fseek( f, 0, SEEK_SET );
2023-01-03 12:56:56 +00:00
auto buf = std::unique_ptr<char[]>( new char[sz] );
2019-08-28 17:28:31 +00:00
fread( buf.get(), 1, sz, f );
fclose( f );
m_description.assign( buf.get(), buf.get() + sz );
2019-07-26 21:05:24 +00:00
}
}
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();
2019-08-28 17:28:31 +00:00
FILE* f = OpenFile( FileDescription, true );
2019-07-26 21:05:24 +00:00
if( !f ) return false;
fwrite( description, 1, sz, f );
fclose( f );
return true;
}
2019-08-28 17:45:22 +00:00
void UserData::LoadState( ViewData& data )
{
assert( Valid() );
FILE* f = OpenFile( FileTimeline, false );
2019-08-28 19:35:08 +00:00
if( f )
2019-08-28 17:45:22 +00:00
{
2019-08-28 19:35:08 +00:00
uint32_t ver;
fread( &ver, 1, sizeof( ver ), f );
if( ver == VersionTimeline )
{
fread( &data.zvStart, 1, sizeof( data.zvStart ), f );
fread( &data.zvEnd, 1, sizeof( data.zvEnd ), f );
//fread( &data.zvHeight, 1, sizeof( data.zvHeight ), f );
fseek( f, sizeof( float ), SEEK_CUR );
//fread( &data.zvScroll, 1, sizeof( data.zvScroll ), f );
fseek( f, sizeof( float ), SEEK_CUR );
2019-08-28 19:35:08 +00:00
fread( &data.frameScale, 1, sizeof( data.frameScale ), f );
fread( &data.frameStart, 1, sizeof( data.frameStart ), f );
}
fclose( f );
}
f = OpenFile( FileOptions, false );
if( f )
{
uint32_t ver;
fread( &ver, 1, sizeof( ver ), f );
if( ver == VersionOptions )
{
fread( &data.drawGpuZones, 1, sizeof( data.drawGpuZones ), f );
fread( &data.drawZones, 1, sizeof( data.drawZones ), f );
fread( &data.drawLocks, 1, sizeof( data.drawLocks ), f );
fread( &data.drawPlots, 1, sizeof( data.drawPlots ), f );
fread( &data.onlyContendedLocks, 1, sizeof( data.onlyContendedLocks ), f );
fread( &data.drawEmptyLabels, 1, sizeof( data.drawEmptyLabels ), f );
2020-11-15 14:46:23 +00:00
fread( &data.drawFrameTargets, 1, sizeof( data.drawFrameTargets ), f );
2019-08-28 19:35:08 +00:00
fread( &data.drawContextSwitches, 1, sizeof( data.drawContextSwitches ), f );
2019-09-30 21:37:36 +00:00
fread( &data.darkenContextSwitches, 1, sizeof( data.darkenContextSwitches ), f );
2019-08-28 19:35:08 +00:00
fread( &data.drawCpuData, 1, sizeof( data.drawCpuData ), f );
2019-10-15 19:37:16 +00:00
fread( &data.drawCpuUsageGraph, 1, sizeof( data.drawCpuUsageGraph ), f );
2020-02-22 16:35:29 +00:00
fread( &data.drawSamples, 1, sizeof( data.drawSamples ), f );
2019-09-08 12:33:30 +00:00
fread( &data.dynamicColors, 1, sizeof( data.dynamicColors ), f );
2020-09-21 00:04:13 +00:00
fread( &data.forceColors, 1, sizeof( data.forceColors ), f );
fread( &data.ghostZones, 1, sizeof( data.ghostZones ), f );
2020-11-15 14:46:23 +00:00
fread( &data.frameTarget, 1, sizeof( data.frameTarget ), f );
2019-08-28 19:35:08 +00:00
}
fclose( f );
2019-08-28 17:45:22 +00:00
}
}
void UserData::SaveState( const ViewData& data )
{
if( !m_preserveState ) return;
assert( Valid() );
FILE* f = OpenFile( FileTimeline, true );
2019-08-28 19:35:08 +00:00
if( f )
{
uint32_t ver = VersionTimeline;
fwrite( &ver, 1, sizeof( ver ), f );
fwrite( &data.zvStart, 1, sizeof( data.zvStart ), f );
fwrite( &data.zvEnd, 1, sizeof( data.zvEnd ), f );
//fwrite( &data.zvHeight, 1, sizeof( data.zvHeight ), f );
float zero = 0;
fwrite( &zero, 1, sizeof( zero ), f );
//fwrite( &data.zvScroll, 1, sizeof( data.zvScroll ), f );
fwrite( &zero, 1, sizeof( zero ), f );
2019-08-28 19:35:08 +00:00
fwrite( &data.frameScale, 1, sizeof( data.frameScale ), f );
fwrite( &data.frameStart, 1, sizeof( data.frameStart ), f );
fclose( f );
}
f = OpenFile( FileOptions, true );
if( f )
{
uint32_t ver = VersionOptions;
fwrite( &ver, 1, sizeof( ver ), f );
fwrite( &data.drawGpuZones, 1, sizeof( data.drawGpuZones ), f );
fwrite( &data.drawZones, 1, sizeof( data.drawZones ), f );
fwrite( &data.drawLocks, 1, sizeof( data.drawLocks ), f );
fwrite( &data.drawPlots, 1, sizeof( data.drawPlots ), f );
fwrite( &data.onlyContendedLocks, 1, sizeof( data.onlyContendedLocks ), f );
fwrite( &data.drawEmptyLabels, 1, sizeof( data.drawEmptyLabels ), f );
2020-11-15 14:46:23 +00:00
fwrite( &data.drawFrameTargets, 1, sizeof( data.drawFrameTargets ), f );
2019-08-28 19:35:08 +00:00
fwrite( &data.drawContextSwitches, 1, sizeof( data.drawContextSwitches ), f );
2019-09-30 21:37:36 +00:00
fwrite( &data.darkenContextSwitches, 1, sizeof( data.darkenContextSwitches ), f );
2019-08-28 19:35:08 +00:00
fwrite( &data.drawCpuData, 1, sizeof( data.drawCpuData ), f );
2019-10-15 19:37:16 +00:00
fwrite( &data.drawCpuUsageGraph, 1, sizeof( data.drawCpuUsageGraph ), f );
2020-02-22 16:35:29 +00:00
fwrite( &data.drawSamples, 1, sizeof( data.drawSamples ), f );
2019-09-08 12:33:30 +00:00
fwrite( &data.dynamicColors, 1, sizeof( data.dynamicColors ), f );
2020-09-21 00:04:13 +00:00
fwrite( &data.forceColors, 1, sizeof( data.forceColors ), f );
fwrite( &data.ghostZones, 1, sizeof( data.ghostZones ), f );
2020-11-15 14:46:23 +00:00
fwrite( &data.frameTarget, 1, sizeof( data.frameTarget ), f );
2019-08-28 19:35:08 +00:00
fclose( f );
}
2019-08-28 17:45:22 +00:00
}
void UserData::StateShouldBePreserved()
{
m_preserveState = true;
}
2019-10-13 14:29:24 +00:00
void UserData::LoadAnnotations( std::vector<std::unique_ptr<Annotation>>& data )
{
assert( Valid() );
FILE* f = OpenFile( FileAnnotations, false );
if( f )
{
uint32_t ver;
fread( &ver, 1, sizeof( ver ), f );
if( ver == VersionAnnotations )
{
uint32_t sz;
fread( &sz, 1, sizeof( sz ), f );
for( uint32_t i=0; i<sz; i++ )
{
auto ann = std::make_unique<Annotation>();
uint32_t tsz;
fread( &tsz, 1, sizeof( tsz ), f );
if( tsz != 0 )
{
char buf[1024];
assert( tsz < 1024 );
fread( buf, 1, tsz, f );
ann->text.assign( buf, tsz );
}
2020-08-04 15:14:58 +00:00
fread( &ann->range.min, 1, sizeof( ann->range.min ), f );
fread( &ann->range.max, 1, sizeof( ann->range.max ), f );
2019-10-13 14:29:24 +00:00
fread( &ann->color, 1, sizeof( ann->color ), f );
2020-08-04 15:23:12 +00:00
ann->range.active = true;
2019-10-13 14:29:24 +00:00
data.emplace_back( std::move( ann ) );
}
}
fclose( f );
}
}
void UserData::SaveAnnotations( const std::vector<std::unique_ptr<Annotation>>& data )
{
if( !m_preserveState ) return;
if( data.empty() )
{
Remove( FileAnnotations );
return;
}
assert( Valid() );
FILE* f = OpenFile( FileAnnotations, true );
if( f )
{
uint32_t ver = VersionAnnotations;
fwrite( &ver, 1, sizeof( ver ), f );
uint32_t sz = uint32_t( data.size() );
fwrite( &sz, 1, sizeof( sz ), f );
for( auto& ann : data )
{
sz = uint32_t( ann->text.size() );
fwrite( &sz, 1, sizeof( sz ), f );
if( sz != 0 )
{
fwrite( ann->text.c_str(), 1, sz, f );
}
2020-08-04 15:14:58 +00:00
fwrite( &ann->range.min, 1, sizeof( ann->range.min ), f );
fwrite( &ann->range.max, 1, sizeof( ann->range.max ), f );
2019-10-13 14:29:24 +00:00
fwrite( &ann->color, 1, sizeof( ann->color ), f );
}
fclose( f );
}
}
2020-04-18 12:25:04 +00:00
bool UserData::LoadSourceSubstitutions( std::vector<SourceRegex>& data )
{
assert( Valid() );
bool regexValid = true;
FILE* f = OpenFile( FileSourceSubstitutions, false );
if( f )
{
uint32_t ver;
fread( &ver, 1, sizeof( ver ), f );
if( ver == VersionSourceSubstitutions )
{
uint32_t sz;
fread( &sz, 1, sizeof( sz ), f );
for( uint32_t i=0; i<sz; i++ )
{
std::string pattern, target;
uint32_t tsz;
fread( &tsz, 1, sizeof( tsz ), f );
if( tsz != 0 )
{
char buf[1024];
assert( tsz < 1024 );
fread( buf, 1, tsz, f );
pattern.assign( buf, tsz );
}
fread( &tsz, 1, sizeof( tsz ), f );
if( tsz != 0 )
{
char buf[1024];
assert( tsz < 1024 );
fread( buf, 1, tsz, f );
target.assign( buf, tsz );
}
std::regex regex;
try
{
regex.assign( pattern );
}
catch( std::regex_error& )
2020-04-18 12:25:04 +00:00
{
regexValid = false;
}
data.emplace_back( SourceRegex { std::move( pattern ), std::move( target ), std::move( regex ) } );
}
}
fclose( f );
}
return regexValid;
}
void UserData::SaveSourceSubstitutions( const std::vector<SourceRegex>& data )
{
if( !m_preserveState ) return;
if( data.empty() )
{
Remove( FileSourceSubstitutions );
return;
}
assert( Valid() );
FILE* f = OpenFile( FileSourceSubstitutions, true );
if( f )
{
uint32_t ver = VersionSourceSubstitutions;
fwrite( &ver, 1, sizeof( ver ), f );
uint32_t sz = uint32_t( data.size() );
fwrite( &sz, 1, sizeof( sz ), f );
for( auto& v : data )
{
sz = uint32_t( v.pattern.size() );
fwrite( &sz, 1, sizeof( sz ), f );
if( sz != 0 )
{
fwrite( v.pattern.c_str(), 1, sz, f );
}
sz = uint32_t( v.target.size() );
fwrite( &sz, 1, sizeof( sz ), f );
if( sz != 0 )
{
fwrite( v.target.c_str(), 1, sz, f );
}
}
fclose( f );
}
}
2019-08-28 17:28:31 +00:00
FILE* UserData::OpenFile( const char* filename, bool write )
{
const auto path = GetSavePath( m_program.c_str(), m_time, filename, write );
if( !path ) return nullptr;
FILE* f = fopen( path, write ? "wb" : "rb" );
return f;
}
2019-10-13 14:29:02 +00:00
void UserData::Remove( const char* filename )
{
const auto path = GetSavePath( m_program.c_str(), m_time, filename, false );
if( !path ) return;
unlink( path );
}
2019-12-28 17:16:45 +00:00
const char* UserData::GetConfigLocation() const
{
assert( Valid() );
return GetSavePath( m_program.c_str(), m_time, nullptr, false );
}
2019-07-26 21:05:24 +00:00
}