VR-Vantage 2.7 API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TracyLua.hpp
Go to the documentation of this file.
1 #ifndef __TRACYLUA_HPP__
2 #define __TRACYLUA_HPP__
3 
4 // Include this file after you include lua headers.
5 
6 #ifndef TRACY_ENABLE
7 
8 #include <string.h>
9 
10 namespace tracy
11 {
12 
13 namespace detail
14 {
15 static inline int noop( lua_State* L ) { return 0; }
16 }
17 
18 static inline void LuaRegister( lua_State* L )
19 {
20  lua_newtable( L );
21  lua_pushcfunction( L, detail::noop );
22  lua_setfield( L, -2, "ZoneBegin" );
23  lua_pushcfunction( L, detail::noop );
24  lua_setfield( L, -2, "ZoneBeginN" );
25  lua_pushcfunction( L, detail::noop );
26  lua_setfield( L, -2, "ZoneBeginS" );
27  lua_pushcfunction( L, detail::noop );
28  lua_setfield( L, -2, "ZoneBeginNS" );
29  lua_pushcfunction( L, detail::noop );
30  lua_setfield( L, -2, "ZoneEnd" );
31  lua_pushcfunction( L, detail::noop );
32  lua_setfield( L, -2, "ZoneText" );
33  lua_pushcfunction( L, detail::noop );
34  lua_setfield( L, -2, "ZoneName" );
35  lua_pushcfunction( L, detail::noop );
36  lua_setfield( L, -2, "Message" );
37  lua_setglobal( L, "tracy" );
38 }
39 
40 static inline char* FindEnd( char* ptr )
41 {
42  unsigned int cnt = 1;
43  while( cnt != 0 )
44  {
45  if( *ptr == '(' ) cnt++;
46  else if( *ptr == ')' ) cnt--;
47  ptr++;
48  }
49  return ptr;
50 }
51 
52 static inline void LuaRemove( char* script )
53 {
54  while( *script )
55  {
56  if( strncmp( script, "tracy.", 6 ) == 0 )
57  {
58  if( strncmp( script + 6, "Zone", 4 ) == 0 )
59  {
60  if( strncmp( script + 10, "End()", 5 ) == 0 )
61  {
62  memset( script, ' ', 15 );
63  script += 15;
64  }
65  else if( strncmp( script + 10, "Begin()", 7 ) == 0 )
66  {
67  memset( script, ' ', 17 );
68  script += 17;
69  }
70  else if( strncmp( script + 10, "Text(", 5 ) == 0 )
71  {
72  auto end = FindEnd( script + 15 );
73  memset( script, ' ', end - script );
74  script = end;
75  }
76  else if( strncmp( script + 10, "Name(", 5 ) == 0 )
77  {
78  auto end = FindEnd( script + 15 );
79  memset( script, ' ', end - script );
80  script = end;
81  }
82  else if( strncmp( script + 10, "BeginN(", 7 ) == 0 )
83  {
84  auto end = FindEnd( script + 17 );
85  memset( script, ' ', end - script );
86  script = end;
87  }
88  else if( strncmp( script + 10, "BeginS(", 7 ) == 0 )
89  {
90  auto end = FindEnd( script + 17 );
91  memset( script, ' ', end - script );
92  script = end;
93  }
94  else if( strncmp( script + 10, "BeginNS(", 8 ) == 0 )
95  {
96  auto end = FindEnd( script + 18 );
97  memset( script, ' ', end - script );
98  script = end;
99  }
100  else
101  {
102  script += 10;
103  }
104  }
105  else if( strncmp( script + 6, "Message(", 8 ) == 0 )
106  {
107  auto end = FindEnd( script + 14 );
108  memset( script, ' ', end - script );
109  script = end;
110  }
111  else
112  {
113  script += 6;
114  }
115  }
116  else
117  {
118  script++;
119  }
120  }
121 }
122 
123 }
124 
125 #else
126 
127 #include <assert.h>
128 #include <limits>
129 
130 #include "common/TracyColor.hpp"
131 #include "common/TracyAlign.hpp"
133 #include "common/TracySystem.hpp"
134 #include "client/TracyProfiler.hpp"
135 
136 namespace tracy
137 {
138 
139 #ifdef TRACY_ON_DEMAND
140 TRACY_API LuaZoneState& GetLuaZoneState();
141 #endif
142 
143 namespace detail
144 {
145 
146 #ifdef TRACY_HAS_CALLSTACK
147 static tracy_force_inline void SendLuaCallstack( lua_State* L, uint32_t depth )
148 {
149  assert( depth <= 64 );
150  lua_Debug dbg[64];
151  const char* func[64];
152  uint32_t fsz[64];
153  uint32_t ssz[64];
154 
155  uint8_t cnt;
156  uint16_t spaceNeeded = sizeof( cnt );
157  for( cnt=0; cnt<depth; cnt++ )
158  {
159  if( lua_getstack( L, cnt+1, dbg+cnt ) == 0 ) break;
160  lua_getinfo( L, "Snl", dbg+cnt );
161  func[cnt] = dbg[cnt].name ? dbg[cnt].name : dbg[cnt].short_src;
162  fsz[cnt] = uint32_t( strlen( func[cnt] ) );
163  ssz[cnt] = uint32_t( strlen( dbg[cnt].source ) );
164  spaceNeeded += fsz[cnt] + ssz[cnt];
165  }
166  spaceNeeded += cnt * ( 4 + 2 + 2 ); // source line, function string length, source string length
167 
168  auto ptr = (char*)tracy_malloc( spaceNeeded + 2 );
169  auto dst = ptr;
170  memcpy( dst, &spaceNeeded, 2 ); dst += 2;
171  memcpy( dst, &cnt, 1 ); dst++;
172  for( uint8_t i=0; i<cnt; i++ )
173  {
174  const uint32_t line = dbg[i].currentline;
175  memcpy( dst, &line, 4 ); dst += 4;
176  assert( fsz[i] <= std::numeric_limits<uint16_t>::max() );
177  memcpy( dst, fsz+i, 2 ); dst += 2;
178  memcpy( dst, func[i], fsz[i] ); dst += fsz[i];
179  assert( ssz[i] <= std::numeric_limits<uint16_t>::max() );
180  memcpy( dst, ssz+i, 2 ); dst += 2;
181  memcpy( dst, dbg[i].source, ssz[i] ), dst += ssz[i];
182  }
183  assert( dst - ptr == spaceNeeded + 2 );
184 
185  TracyLfqPrepare( QueueType::CallstackAlloc );
186  MemWrite( &item->callstackAllocFat.ptr, (uint64_t)ptr );
187  MemWrite( &item->callstackAllocFat.nativePtr, (uint64_t)Callstack( depth ) );
189 }
190 
191 static inline int LuaZoneBeginS( lua_State* L )
192 {
193 #ifdef TRACY_ON_DEMAND
194  const auto zoneCnt = GetLuaZoneState().counter++;
195  if( zoneCnt != 0 && !GetLuaZoneState().active ) return 0;
196  GetLuaZoneState().active = GetProfiler().IsConnected();
197  if( !GetLuaZoneState().active ) return 0;
198 #endif
199 
200  TracyLfqPrepare( QueueType::ZoneBeginAllocSrcLocCallstack );
201  lua_Debug dbg;
202  lua_getstack( L, 1, &dbg );
203  lua_getinfo( L, "Snl", &dbg );
204  const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, dbg.source, dbg.name ? dbg.name : dbg.short_src );
205  MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
206  MemWrite( &item->zoneBegin.srcloc, srcloc );
208 
209 #ifdef TRACY_CALLSTACK
210  const uint32_t depth = TRACY_CALLSTACK;
211 #else
212  const auto depth = uint32_t( lua_tointeger( L, 1 ) );
213 #endif
214  SendLuaCallstack( L, depth );
215 
216  return 0;
217 }
218 
219 static inline int LuaZoneBeginNS( lua_State* L )
220 {
221 #ifdef TRACY_ON_DEMAND
222  const auto zoneCnt = GetLuaZoneState().counter++;
223  if( zoneCnt != 0 && !GetLuaZoneState().active ) return 0;
224  GetLuaZoneState().active = GetProfiler().IsConnected();
225  if( !GetLuaZoneState().active ) return 0;
226 #endif
227 
228  TracyLfqPrepare( QueueType::ZoneBeginAllocSrcLocCallstack );
229  lua_Debug dbg;
230  lua_getstack( L, 1, &dbg );
231  lua_getinfo( L, "Snl", &dbg );
232  size_t nsz;
233  const auto name = lua_tolstring( L, 1, &nsz );
234  const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, dbg.source, dbg.name ? dbg.name : dbg.short_src, name, nsz );
235  MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
236  MemWrite( &item->zoneBegin.srcloc, srcloc );
238 
239 #ifdef TRACY_CALLSTACK
240  const uint32_t depth = TRACY_CALLSTACK;
241 #else
242  const auto depth = uint32_t( lua_tointeger( L, 2 ) );
243 #endif
244  SendLuaCallstack( L, depth );
245 
246  return 0;
247 }
248 #endif
249 
250 static inline int LuaZoneBegin( lua_State* L )
251 {
252 #if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
253  return LuaZoneBeginS( L );
254 #else
255 #ifdef TRACY_ON_DEMAND
256  const auto zoneCnt = GetLuaZoneState().counter++;
257  if( zoneCnt != 0 && !GetLuaZoneState().active ) return 0;
258  GetLuaZoneState().active = GetProfiler().IsConnected();
259  if( !GetLuaZoneState().active ) return 0;
260 #endif
261 
262  TracyLfqPrepare( QueueType::ZoneBeginAllocSrcLoc );
263  lua_Debug dbg;
264  lua_getstack( L, 1, &dbg );
265  lua_getinfo( L, "Snl", &dbg );
266  const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, dbg.source, dbg.name ? dbg.name : dbg.short_src );
267  MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
268  MemWrite( &item->zoneBegin.srcloc, srcloc );
270  return 0;
271 #endif
272 }
273 
274 static inline int LuaZoneBeginN( lua_State* L )
275 {
276 #if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
277  return LuaZoneBeginNS( L );
278 #else
279 #ifdef TRACY_ON_DEMAND
280  const auto zoneCnt = GetLuaZoneState().counter++;
281  if( zoneCnt != 0 && !GetLuaZoneState().active ) return 0;
282  GetLuaZoneState().active = GetProfiler().IsConnected();
283  if( !GetLuaZoneState().active ) return 0;
284 #endif
285 
286  TracyLfqPrepare( QueueType::ZoneBeginAllocSrcLoc );
287  lua_Debug dbg;
288  lua_getstack( L, 1, &dbg );
289  lua_getinfo( L, "Snl", &dbg );
290  size_t nsz;
291  const auto name = lua_tolstring( L, 1, &nsz );
292  const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, dbg.source, dbg.name ? dbg.name : dbg.short_src, name, nsz );
293  MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
294  MemWrite( &item->zoneBegin.srcloc, srcloc );
296  return 0;
297 #endif
298 }
299 
300 static inline int LuaZoneEnd( lua_State* L )
301 {
302 #ifdef TRACY_ON_DEMAND
303  assert( GetLuaZoneState().counter != 0 );
304  GetLuaZoneState().counter--;
305  if( !GetLuaZoneState().active ) return 0;
306  if( !GetProfiler().IsConnected() )
307  {
308  GetLuaZoneState().active = false;
309  return 0;
310  }
311 #endif
312 
313  TracyLfqPrepare( QueueType::ZoneEnd );
314  MemWrite( &item->zoneEnd.time, Profiler::GetTime() );
316  return 0;
317 }
318 
319 static inline int LuaZoneText( lua_State* L )
320 {
321 #ifdef TRACY_ON_DEMAND
322  if( !GetLuaZoneState().active ) return 0;
323  if( !GetProfiler().IsConnected() )
324  {
325  GetLuaZoneState().active = false;
326  return 0;
327  }
328 #endif
329 
330  auto txt = lua_tostring( L, 1 );
331  const auto size = strlen( txt );
333 
334  auto ptr = (char*)tracy_malloc( size );
335  memcpy( ptr, txt, size );
337  MemWrite( &item->zoneTextFat.text, (uint64_t)ptr );
338  MemWrite( &item->zoneTextFat.size, (uint16_t)size );
340  return 0;
341 }
342 
343 static inline int LuaZoneName( lua_State* L )
344 {
345 #ifdef TRACY_ON_DEMAND
346  if( !GetLuaZoneState().active ) return 0;
347  if( !GetProfiler().IsConnected() )
348  {
349  GetLuaZoneState().active = false;
350  return 0;
351  }
352 #endif
353 
354  auto txt = lua_tostring( L, 1 );
355  const auto size = strlen( txt );
357 
358  auto ptr = (char*)tracy_malloc( size );
359  memcpy( ptr, txt, size );
361  MemWrite( &item->zoneTextFat.text, (uint64_t)ptr );
362  MemWrite( &item->zoneTextFat.size, (uint16_t)size );
364  return 0;
365 }
366 
367 static inline int LuaMessage( lua_State* L )
368 {
369 #ifdef TRACY_ON_DEMAND
370  if( !GetProfiler().IsConnected() ) return 0;
371 #endif
372 
373  auto txt = lua_tostring( L, 1 );
374  const auto size = strlen( txt );
376 
377  TracyLfqPrepare( QueueType::Message );
378  auto ptr = (char*)tracy_malloc( size );
379  memcpy( ptr, txt, size );
380  MemWrite( &item->messageFat.time, Profiler::GetTime() );
381  MemWrite( &item->messageFat.text, (uint64_t)ptr );
382  MemWrite( &item->messageFat.size, (uint16_t)size );
384  return 0;
385 }
386 
387 }
388 
389 static inline void LuaRegister( lua_State* L )
390 {
391  lua_newtable( L );
392  lua_pushcfunction( L, detail::LuaZoneBegin );
393  lua_setfield( L, -2, "ZoneBegin" );
394  lua_pushcfunction( L, detail::LuaZoneBeginN );
395  lua_setfield( L, -2, "ZoneBeginN" );
396 #ifdef TRACY_HAS_CALLSTACK
397  lua_pushcfunction( L, detail::LuaZoneBeginS );
398  lua_setfield( L, -2, "ZoneBeginS" );
399  lua_pushcfunction( L, detail::LuaZoneBeginNS );
400  lua_setfield( L, -2, "ZoneBeginNS" );
401 #else
402  lua_pushcfunction( L, detail::LuaZoneBegin );
403  lua_setfield( L, -2, "ZoneBeginS" );
404  lua_pushcfunction( L, detail::LuaZoneBeginN );
405  lua_setfield( L, -2, "ZoneBeginNS" );
406 #endif
407  lua_pushcfunction( L, detail::LuaZoneEnd );
408  lua_setfield( L, -2, "ZoneEnd" );
409  lua_pushcfunction( L, detail::LuaZoneText );
410  lua_setfield( L, -2, "ZoneText" );
411  lua_pushcfunction( L, detail::LuaZoneName );
412  lua_setfield( L, -2, "ZoneName" );
413  lua_pushcfunction( L, detail::LuaMessage );
414  lua_setfield( L, -2, "Message" );
415  lua_setglobal( L, "tracy" );
416 }
417 
418 static inline void LuaRemove( char* script ) {}
419 
420 }
421 
422 #endif
423 
424 #endif


Copyright © 2005-2021 MAK Technologies. All Rights Reserved (www.mak.com)