use minidl::Library;
#[repr(C)]
pub struct SourceLocation {
pub name: *const u8,
pub function: *const u8,
pub file: *const u8,
pub line: u32,
pub color: u32,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct ZoneContext {
id: u32,
active: i32,
}
extern "C" fn unimpl_mark_frame(_: *const u8) {}
extern "C" fn unimpl_mark_frame_start(_: *const u8) {}
extern "C" fn unimpl_mark_frame_end(_: *const u8) {}
extern "C" fn unimpl_zone_begin(_: *const SourceLocation, _: i32) -> ZoneContext {
ZoneContext {
id: 0,
active: 0,
}
}
extern "C" fn unimpl_zone_end(_: ZoneContext) {}
extern "C" fn unimpl_zone_text(_: ZoneContext, _: *const u8, _: usize) {}
extern "C" fn unimpl_plot(_: *const u8, _: f64) {}
pub static mut MARK_FRAME: extern "C" fn(name: *const u8) = unimpl_mark_frame;
pub static mut MARK_FRAME_START: extern "C" fn(name: *const u8) = unimpl_mark_frame_start;
pub static mut MARK_FRAME_END: extern "C" fn(name: *const u8) = unimpl_mark_frame_end;
pub static mut EMIT_ZONE_BEGIN: extern "C" fn(srcloc: *const SourceLocation, active: i32) -> ZoneContext = unimpl_zone_begin;
pub static mut EMIT_ZONE_END: extern "C" fn(ctx: ZoneContext) = unimpl_zone_end;
pub static mut EMIT_ZONE_TEXT: extern "C" fn(ctx: ZoneContext, txt: *const u8, size: usize) = unimpl_zone_text;
pub static mut EMIT_PLOT: extern "C" fn(name: *const u8, val: f64) = unimpl_plot;
pub unsafe fn load(path: &str) -> bool {
match Library::load(path) {
Ok(lib) => {
MARK_FRAME = lib.sym("___tracy_emit_frame_mark\0").unwrap();
MARK_FRAME_START = lib.sym("___tracy_emit_frame_mark_start\0").unwrap();
MARK_FRAME_END = lib.sym("___tracy_emit_frame_mark_end\0").unwrap();
EMIT_ZONE_BEGIN = lib.sym("___tracy_emit_zone_begin\0").unwrap();
EMIT_ZONE_END = lib.sym("___tracy_emit_zone_end\0").unwrap();
EMIT_ZONE_TEXT = lib.sym("___tracy_emit_zone_text\0").unwrap();
EMIT_PLOT = lib.sym("___tracy_emit_plot\0").unwrap();
true
}
Err(..) => {
println!("Failed to load the tracy profiling library!");
false
}
}
}
pub struct ProfileScope {
ctx: ZoneContext,
}
impl ProfileScope {
pub fn new(callsite: &'static SourceLocation) -> Self {
let ctx = unsafe { EMIT_ZONE_BEGIN(callsite, 1) };
ProfileScope {
ctx,
}
}
}
impl Drop for ProfileScope {
fn drop(&mut self) {
unsafe {
EMIT_ZONE_END(self.ctx)
}
}
}
#[macro_export]
macro_rules! profile_scope {
($string:expr) => {
const CALLSITE: $crate::profiler::SourceLocation = $crate::profiler::SourceLocation {
name: concat!($string, "\0").as_ptr(),
function: concat!(module_path!(), "\0").as_ptr(),
file: concat!(file!(), "\0").as_ptr(),
line: line!(),
color: 0xff0000ff,
};
let _profile_scope = $crate::profiler::ProfileScope::new(&CALLSITE);
}
}
#[macro_export]
macro_rules! tracy_frame_marker {
() => {
unsafe {
$crate::profiler::MARK_FRAME(std::ptr::null())
}
}
}
#[macro_export]
macro_rules! tracy_begin_frame {
($name:expr) => {
unsafe {
$crate::profiler::MARK_FRAME_START(concat!($name, "\0").as_ptr())
}
}
}
#[macro_export]
macro_rules! tracy_end_frame {
($name:expr) => {
unsafe {
$crate::profiler::MARK_FRAME_END(concat!($name, "\0").as_ptr())
}
}
}
#[macro_export]
macro_rules! tracy_plot {
($name:expr, $value:expr) => {
unsafe {
$crate::profiler::EMIT_PLOT(concat!($name, "\0").as_ptr(), $value)
}
}
}
pub fn register_thread_with_profiler(_: String) {
}