profiling/
tracy_impl.rs

1#[macro_export]
2macro_rules! scope {
3    // Note: literal patterns provided as an optimization since they can skip an allocation.
4    ($name:literal) => {
5        // Note: callstack_depth is 0 since this has significant overhead
6        let _tracy_span = $crate::tracy_client::span!($name, 0);
7    };
8    ($name:literal, $data:expr) => {
9        // Note: callstack_depth is 0 since this has significant overhead
10        let _tracy_span = $crate::tracy_client::span!($name, 0);
11        _tracy_span.emit_text($data);
12    };
13    ($name:expr) => {
14        let _function_name = {
15            struct S;
16            let type_name = core::any::type_name::<S>();
17            &type_name[..type_name.len() - 3]
18        };
19        let _tracy_span = $crate::tracy_client::Client::running()
20            .expect("scope! without a running tracy_client::Client")
21            // Note: callstack_depth is 0 since this has significant overhead
22            .span_alloc(Some($name), _function_name, file!(), line!(), 0);
23    };
24    ($name:expr, $data:expr) => {
25        let _function_name = {
26            struct S;
27            let type_name = core::any::type_name::<S>();
28            &type_name[..type_name.len() - 3]
29        };
30        let _tracy_span = $crate::tracy_client::Client::running()
31            .expect("scope! without a running tracy_client::Client")
32            // Note: callstack_depth is 0 since this has significant overhead
33            .span_alloc(Some($name), _function_name, file!(), line!(), 0);
34        _tracy_span.emit_text($data);
35    };
36}
37
38#[macro_export]
39macro_rules! function_scope {
40    () => {
41        let _tracy_span = $crate::tracy_client::span!();
42    };
43    ($data:expr) => {
44        let _location = $crate::tracy_client::span_location!();
45        let _tracy_span = $crate::tracy_client::Client::running()
46            .expect("function_scope! without a running tracy_client::Client")
47            .span(_location, 0);
48        _tracy_span.emit_text($data);
49    };
50}
51
52/// Registers a thread with the profiler API(s). This is usually setting a name for the thread.
53/// Two variants:
54///  - register_thread!() - Tries to get the name of the thread, or an ID if no name is set
55///  - register_thread!(name: &str) - Registers the thread using the given name
56#[macro_export]
57macro_rules! register_thread {
58    () => {
59        let thread_name = std::thread::current()
60            .name()
61            .map(|x| x.to_string())
62            .unwrap_or_else(|| format!("Thread {:?}", std::thread::current().id()));
63
64        $crate::register_thread!(&thread_name);
65    };
66    ($name:expr) => {
67        $crate::tracy_client::Client::running()
68            .expect("register_thread! without a running tracy_client::Client")
69            .set_thread_name($name);
70    };
71}
72
73/// Finishes the frame. This isn't strictly necessary for some kinds of applications but a pretty
74/// normal thing to track in games.
75#[macro_export]
76macro_rules! finish_frame {
77    () => {
78        $crate::tracy_client::Client::running()
79            .expect("finish_frame! without a running tracy_client::Client")
80            .frame_mark();
81    };
82}