Gaia-ECS v0.9.3
A simple and powerful entity component system
Loading...
Searching...
No Matches
profiler.h
1#pragma once
2#include "gaia/config/config.h"
3#include "gaia/core/utility.h"
4
5#ifndef GAIA_PROFILER_CPU
6 #define GAIA_PROFILER_CPU 0
7#endif
8#ifndef GAIA_PROFILER_MEM
9 #define GAIA_PROFILER_MEM 0
10#endif
11
12#if GAIA_PROFILER_CPU || GAIA_PROFILER_MEM
13// Keep it small on Windows
14// TODO: What if user doesn't want this?
15// #if GAIA_PLATFORM_WINDOWS && !defined(WIN32_LEAN_AND_MEAN)
16// #define WIN32_LEAN_AND_MEAN
17// #endif
18GAIA_MSVC_WARNING_PUSH()
19GAIA_MSVC_WARNING_DISABLE(4668)
20 #include <tracy/Tracy.hpp>
21 #include <tracy/TracyC.h>
22GAIA_MSVC_WARNING_POP()
23#endif
24
25#if GAIA_PROFILER_CPU
26
27namespace tracy {
28 inline constexpr size_t TracyFileMaxLen = 4096;
29 inline constexpr size_t TracyFunctionMaxLen = 16384;
30 inline constexpr size_t TracyZoneNameMaxLen = 128;
31
32 template <class T>
33 class gaia_LockableExt: public Lockable<T> {
34 public:
35 tracy_force_inline gaia_LockableExt(const SourceLocationData* srcloc): Lockable<T>(srcloc) {}
36
41 T& get_lock() {
42 // Assuming TLockable is non-virtual and the memory layout is as follows:
43 // T m_lockable;
44 // LockableCtx m_ctx;
45 // ...
46 //
47 // m_lockable is the first member. We simply cast to it.
48 T* ptr_lockable = reinterpret_cast<T*>(this);
49 return (T&)*(ptr_lockable + 0);
50 // return (T&)m_lockable;
51 }
52 };
53 #define LockableBaseExt(type) tracy::gaia_LockableExt<type>
54 #define TracyLockableExt(type, varname) \
55 tracy::gaia_LockableExt<type> varname { \
56 []() -> const tracy::SourceLocationData* { \
57 static constexpr tracy::SourceLocationData srcloc{nullptr, #type " " #varname, TracyFile, TracyLine, 0}; \
58 return &srcloc; \
59 }() \
60 }
61
63 struct ZoneRT {
64 TracyCZoneCtx m_ctx;
65
66 ZoneRT(const char* name, const char* file, uint32_t line, const char* function) {
67 const auto srcloc = ___tracy_alloc_srcloc_name(
68 line, file, GAIA_STRLEN(file, TracyFileMaxLen), function, GAIA_STRLEN(function, TracyFunctionMaxLen), name,
69 GAIA_STRLEN(name, TracyZoneNameMaxLen), 0);
70 m_ctx = ___tracy_emit_zone_begin_alloc(srcloc, 1);
71 }
72 ~ZoneRT() {
73 TracyCZoneEnd(m_ctx);
74 }
75 };
76
77 struct ScopeStack {
78 static constexpr uint32_t StackSize = 64;
79
80 uint32_t count;
81 TracyCZoneCtx buffer[StackSize];
82 };
83
84 inline thread_local ScopeStack t_ScopeStack;
85
86 inline void ZoneBegin(const ___tracy_source_location_data* srcloc) {
87 auto& stack = t_ScopeStack;
88 const auto pos = stack.count++;
89 if (pos < ScopeStack::StackSize) {
90 stack.buffer[pos] = ___tracy_emit_zone_begin(srcloc, 1);
91 }
92 }
93
94 inline void ZoneRTBegin(uint64_t srcloc) {
95 auto& stack = t_ScopeStack;
96 const auto pos = stack.count++;
97 if (pos < ScopeStack::StackSize)
98 stack.buffer[pos] = ___tracy_emit_zone_begin_alloc(srcloc, 1);
99 }
100
101 inline void ZoneEnd() {
102 auto& stack = t_ScopeStack;
103 GAIA_ASSERT(stack.count > 0);
104 const auto pos = --stack.count;
105 if (pos < ScopeStack::StackSize)
106 ___tracy_emit_zone_end(stack.buffer[pos]);
107 }
108} // namespace tracy
109
110 #define TRACY_ZoneNamedRT(name, function) \
111 tracy::ZoneRT TracyConcat(__tracy_zone_dynamic, __LINE__)(name, __FILE__, __LINE__, function);
112
113 #define TRACY_ZoneNamedRTBegin(name, function) \
114 tracy::ZoneRTBegin(___tracy_alloc_srcloc_name( \
115 __LINE__, __FILE__, GAIA_STRLEN(__FILE__, tracy::TracyFileMaxLen), function, \
116 GAIA_STRLEN(function, tracy::TracyFunctionMaxLen), name, GAIA_STRLEN(name, tracy::TracyZoneNameMaxLen), 0));
117
118 #define TRACY_ZoneBegin(name, function) \
119 static constexpr ___tracy_source_location_data TracyConcat(__tracy_source_location, __LINE__) { \
120 name "", function, __FILE__, uint32_t(__LINE__), 0, \
121 }
122 #define TRACY_ZoneEnd() tracy::ZoneEnd
123
124 #define GAIA_PROF_START_IMPL(name, function) \
125 TRACY_ZoneBegin(name, function); \
126 tracy::ZoneBegin(&TracyConcat(__tracy_source_location, __LINE__));
127
128 #define GAIA_PROF_STOP_IMPL() TRACY_ZoneEnd()
129
130 #define GAIA_PROF_SCOPE_IMPL(name) ZoneNamedN(GAIA_CONCAT(___tracy_scoped_zone_, __LINE__), name "", 1)
131 #define GAIA_PROF_SCOPE_DYN_IMPL(name) TRACY_ZoneNamedRT(name, GAIA_PRETTY_FUNCTION)
132
133//------------------------------------------------------------------------
134// Tracy profiler GAIA implementation
135//------------------------------------------------------------------------
136
138 #if !defined(GAIA_PROF_FRAME)
139 #define GAIA_PROF_FRAME() FrameMark
140 #endif
142 #if !defined(GAIA_PROF_SCOPE)
143 #define GAIA_PROF_SCOPE(zoneName) GAIA_PROF_SCOPE_IMPL(#zoneName)
144 #endif
146 #if !defined(GAIA_PROF_SCOPE2)
147 #define GAIA_PROF_SCOPE2(zoneName) GAIA_PROF_SCOPE_DYN_IMPL(zoneName)
148 #endif
150 #if !defined(GAIA_PROF_START)
151 #define GAIA_PROF_START(zoneName) GAIA_PROF_START_IMPL(#zoneName, GAIA_PRETTY_FUNCTION)
152 #endif
154 #if !defined(GAIA_PROF_STOP)
155 #define GAIA_PROF_STOP() GAIA_PROF_STOP_IMPL()
156 #endif
158 #if !defined(GAIA_PROF_MUTEX_BASE)
159 #define GAIA_PROF_EXTRACT_MUTEX(name) (name).get_lock()
160 #define GAIA_PROF_MUTEX_BASE(type) LockableBaseExt<type>
161 #define GAIA_PROF_LOCK_MARK(name) LockMark(name)
162 #endif
163 #if !defined(GAIA_PROF_MUTEX)
164 #define GAIA_PROF_MUTEX(type, name) TracyLockableExt(type, name)
165 #endif
167 #if !defined(GAIA_PROF_USE_PROFILER_THREAD_NAME)
168 #define GAIA_PROF_USE_PROFILER_THREAD_NAME 1
169 #endif
171 #if !defined(GAIA_PROF_THREAD_NAME)
172 #define GAIA_PROF_THREAD_NAME(name) tracy::SetThreadName(name)
173 #endif
174#else
176 #if !defined(GAIA_PROF_FRAME)
177 #define GAIA_PROF_FRAME()
178 #endif
180 #if !defined(GAIA_PROF_SCOPE)
181 #define GAIA_PROF_SCOPE(zoneName)
182 #endif
184 #if !defined(GAIA_PROF_SCOPE2)
185 #define GAIA_PROF_SCOPE2(zoneName)
186 #endif
188 #if !defined(GAIA_PROF_START)
189 #define GAIA_PROF_START(zoneName)
190 #endif
192 #if !defined(GAIA_PROF_STOP)
193 #define GAIA_PROF_STOP()
194 #endif
196 #if !defined(GAIA_PROF_MUTEX_BASE)
197 #define GAIA_PROF_EXTRACT_MUTEX(name) name
198 #define GAIA_PROF_MUTEX_BASE(type) type
199 #define GAIA_PROF_LOCK_MARK(name)
200 #endif
201 #if !defined(GAIA_PROF_MUTEX)
202 #define GAIA_PROF_MUTEX(type, name) GAIA_PROF_MUTEX_BASE(type) name
203 #endif
205 #if !defined(GAIA_PROF_USE_PROFILER_THREAD_NAME)
206 #define GAIA_PROF_USE_PROFILER_THREAD_NAME 0
207 #endif
209 #if !defined(GAIA_PROF_THREAD_NAME)
210 #define GAIA_PROF_THREAD_NAME(name)
211 #endif
212#endif
213
214#if GAIA_PROFILER_MEM
216 #if !defined(GAIA_PROF_ALLOC)
217 #define GAIA_PROF_ALLOC(ptr, size) TracyAlloc(ptr, size)
218 #endif
220 #if !defined(GAIA_PROF_ALLOC2)
221 #define GAIA_PROF_ALLOC2(ptr, size, name) TracyAllocN(ptr, size, name)
222 #endif
224 #if !defined(GAIA_PROF_FREE)
225 #define GAIA_PROF_FREE(ptr) TracyFree(ptr)
226 #endif
228 #if !defined(GAIA_PROF_FREE2)
229 #define GAIA_PROF_FREE2(ptr, name) TracyFreeN(ptr, name)
230 #endif
231#else
233 #if !defined(GAIA_PROF_ALLOC)
234 #define GAIA_PROF_ALLOC(ptr, size)
235 #endif
237 #if !defined(GAIA_PROF_ALLOC2)
238 #define GAIA_PROF_ALLOC2(ptr, size, name)
239 #endif
241 #if !defined(GAIA_PROF_FREE)
242 #define GAIA_PROF_FREE(ptr)
243 #endif
245 #if !defined(GAIA_PROF_FREE2)
246 #define GAIA_PROF_FREE2(ptr, name)
247 #endif
248#endif