The open source OpenXR runtime
1#ifndef __TRACYSCOPED_HPP__
2#define __TRACYSCOPED_HPP__
3
4#include <limits>
5#include <stdint.h>
6#include <string.h>
7
8#include "../common/TracySystem.hpp"
9#include "../common/TracyAlign.hpp"
10#include "../common/TracyAlloc.hpp"
11#include "TracyProfiler.hpp"
12
13namespace tracy
14{
15
16class ScopedZone
17{
18public:
19 ScopedZone( const ScopedZone& ) = delete;
20 ScopedZone( ScopedZone&& ) = delete;
21 ScopedZone& operator=( const ScopedZone& ) = delete;
22 ScopedZone& operator=( ScopedZone&& ) = delete;
23
24 tracy_force_inline ScopedZone( const SourceLocationData* srcloc, bool is_active = true )
25#ifdef TRACY_ON_DEMAND
26 : m_active( is_active && GetProfiler().IsConnected() )
27#else
28 : m_active( is_active )
29#endif
30 {
31 if( !m_active ) return;
32#ifdef TRACY_ON_DEMAND
33 m_connectionId = GetProfiler().ConnectionId();
34#endif
35 TracyQueuePrepare( QueueType::ZoneBegin );
36 MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
37 MemWrite( &item->zoneBegin.srcloc, (uint64_t)srcloc );
38 TracyQueueCommit( zoneBeginThread );
39 }
40
41 tracy_force_inline ScopedZone( const SourceLocationData* srcloc, int depth, bool is_active = true )
42#ifdef TRACY_ON_DEMAND
43 : m_active( is_active && GetProfiler().IsConnected() )
44#else
45 : m_active( is_active )
46#endif
47 {
48 if( !m_active ) return;
49#ifdef TRACY_ON_DEMAND
50 m_connectionId = GetProfiler().ConnectionId();
51#endif
52 GetProfiler().SendCallstack( depth );
53
54 TracyQueuePrepare( QueueType::ZoneBeginCallstack );
55 MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
56 MemWrite( &item->zoneBegin.srcloc, (uint64_t)srcloc );
57 TracyQueueCommit( zoneBeginThread );
58 }
59
60 tracy_force_inline ScopedZone( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, bool is_active = true )
61#ifdef TRACY_ON_DEMAND
62 : m_active( is_active && GetProfiler().IsConnected() )
63#else
64 : m_active( is_active )
65#endif
66 {
67 if( !m_active ) return;
68#ifdef TRACY_ON_DEMAND
69 m_connectionId = GetProfiler().ConnectionId();
70#endif
71 TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLoc );
72 const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
73 MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
74 MemWrite( &item->zoneBegin.srcloc, srcloc );
75 TracyQueueCommit( zoneBeginThread );
76 }
77
78 tracy_force_inline ScopedZone( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, int depth, bool is_active = true )
79#ifdef TRACY_ON_DEMAND
80 : m_active( is_active && GetProfiler().IsConnected() )
81#else
82 : m_active( is_active )
83#endif
84 {
85 if( !m_active ) return;
86#ifdef TRACY_ON_DEMAND
87 m_connectionId = GetProfiler().ConnectionId();
88#endif
89 GetProfiler().SendCallstack( depth );
90
91 TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLocCallstack );
92 const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
93 MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
94 MemWrite( &item->zoneBegin.srcloc, srcloc );
95 TracyQueueCommit( zoneBeginThread );
96 }
97
98 tracy_force_inline ~ScopedZone()
99 {
100 if( !m_active ) return;
101#ifdef TRACY_ON_DEMAND
102 if( GetProfiler().ConnectionId() != m_connectionId ) return;
103#endif
104 TracyQueuePrepare( QueueType::ZoneEnd );
105 MemWrite( &item->zoneEnd.time, Profiler::GetTime() );
106 TracyQueueCommit( zoneEndThread );
107 }
108
109 tracy_force_inline void Text( const char* txt, size_t size )
110 {
111 assert( size < std::numeric_limits<uint16_t>::max() );
112 if( !m_active ) return;
113#ifdef TRACY_ON_DEMAND
114 if( GetProfiler().ConnectionId() != m_connectionId ) return;
115#endif
116 auto ptr = (char*)tracy_malloc( size );
117 memcpy( ptr, txt, size );
118 TracyQueuePrepare( QueueType::ZoneText );
119 MemWrite( &item->zoneTextFat.text, (uint64_t)ptr );
120 MemWrite( &item->zoneTextFat.size, (uint16_t)size );
121 TracyQueueCommit( zoneTextFatThread );
122 }
123
124 tracy_force_inline void Name( const char* txt, size_t size )
125 {
126 assert( size < std::numeric_limits<uint16_t>::max() );
127 if( !m_active ) return;
128#ifdef TRACY_ON_DEMAND
129 if( GetProfiler().ConnectionId() != m_connectionId ) return;
130#endif
131 auto ptr = (char*)tracy_malloc( size );
132 memcpy( ptr, txt, size );
133 TracyQueuePrepare( QueueType::ZoneName );
134 MemWrite( &item->zoneTextFat.text, (uint64_t)ptr );
135 MemWrite( &item->zoneTextFat.size, (uint16_t)size );
136 TracyQueueCommit( zoneTextFatThread );
137 }
138
139 tracy_force_inline void Color( uint32_t color )
140 {
141 if( !m_active ) return;
142#ifdef TRACY_ON_DEMAND
143 if( GetProfiler().ConnectionId() != m_connectionId ) return;
144#endif
145 TracyQueuePrepare( QueueType::ZoneColor );
146 MemWrite( &item->zoneColor.b, uint8_t( ( color ) & 0xFF ) );
147 MemWrite( &item->zoneColor.g, uint8_t( ( color >> 8 ) & 0xFF ) );
148 MemWrite( &item->zoneColor.r, uint8_t( ( color >> 16 ) & 0xFF ) );
149 TracyQueueCommit( zoneColorThread );
150 }
151
152 tracy_force_inline void Value( uint64_t value )
153 {
154 if( !m_active ) return;
155#ifdef TRACY_ON_DEMAND
156 if( GetProfiler().ConnectionId() != m_connectionId ) return;
157#endif
158 TracyQueuePrepare( QueueType::ZoneValue );
159 MemWrite( &item->zoneValue.value, value );
160 TracyQueueCommit( zoneValueThread );
161 }
162
163 tracy_force_inline bool IsActive() const { return m_active; }
164
165private:
166 const bool m_active;
167
168#ifdef TRACY_ON_DEMAND
169 uint64_t m_connectionId = 0;
170#endif
171};
172
173}
174
175#endif