sokoban-v2/libs/tracy/src/root.zig

352 lines
11 KiB
Zig

const std = @import("std");
const digits2 = std.fmt.digits2;
const builtin = @import("builtin");
const options = @import("options");
const c = @import("c");
pub inline fn setThreadName(comptime name: [:0]const u8) void {
if (!options.tracy_enable) return;
c.___tracy_set_thread_name(name);
}
pub inline fn startupProfiler() void {
if (!options.tracy_enable) return;
if (!options.tracy_manual_lifetime) return;
c.___tracy_startup_profiler();
}
pub inline fn shutdownProfiler() void {
if (!options.tracy_enable) return;
if (!options.tracy_manual_lifetime) return;
c.___tracy_shutdown_profiler();
}
pub inline fn profilerStarted() bool {
if (!options.tracy_enable) return false;
if (!options.tracy_manual_lifetime) return true;
return c.___tracy_profiler_started() != 0;
}
pub inline fn isConnected() bool {
if (!options.tracy_enable) return false;
return c.___tracy_connected() > 0;
}
pub inline fn frameMark() void {
if (!options.tracy_enable) return;
c.___tracy_emit_frame_mark(null);
}
pub inline fn frameMarkNamed(comptime name: [:0]const u8) void {
if (!options.tracy_enable) return;
c.___tracy_emit_frame_mark(name);
}
const DiscontinuousFrame = struct {
name: [:0]const u8,
pub inline fn deinit(frame: *const DiscontinuousFrame) void {
if (!options.tracy_enable) return;
c.___tracy_emit_frame_mark_end(frame.name);
}
};
pub inline fn initDiscontinuousFrame(comptime name: [:0]const u8) DiscontinuousFrame {
if (!options.tracy_enable) return .{ .name = name };
c.___tracy_emit_frame_mark_start(name);
return .{ .name = name };
}
pub inline fn frameImage(image: *anyopaque, width: u16, height: u16, offset: u8, flip: bool) void {
if (!options.tracy_enable) return;
c.___tracy_emit_frame_mark_image(image, width, height, offset, @as(c_int, @intFromBool(flip)));
}
pub const ZoneOptions = struct {
active: bool = true,
name: ?[]const u8 = null,
color: ?u32 = null,
};
const ZoneContext = if (options.tracy_enable) extern struct {
ctx: c.___tracy_c_zone_context,
pub inline fn deinit(zone: *const ZoneContext) void {
if (!options.tracy_enable) return;
c.___tracy_emit_zone_end(zone.ctx);
}
pub inline fn name(zone: *const ZoneContext, zone_name: []const u8) void {
if (!options.tracy_enable) return;
c.___tracy_emit_zone_name(zone.ctx, zone_name.ptr, zone_name.len);
}
pub inline fn text(zone: *const ZoneContext, zone_text: []const u8) void {
if (!options.tracy_enable) return;
c.___tracy_emit_zone_text(zone.ctx, zone_text.ptr, zone_text.len);
}
pub inline fn color(zone: *const ZoneContext, zone_color: u32) void {
if (!options.tracy_enable) return;
c.___tracy_emit_zone_color(zone.ctx, zone_color);
}
pub inline fn value(zone: *const ZoneContext, zone_value: u64) void {
if (!options.tracy_enable) return;
c.___tracy_emit_zone_value(zone.ctx, zone_value);
}
} else struct {
pub inline fn deinit(_: *const ZoneContext) void {}
pub inline fn name(_: *const ZoneContext, _: []const u8) void {}
pub inline fn text(_: *const ZoneContext, _: []const u8) void {}
pub inline fn color(_: *const ZoneContext, _: u32) void {}
pub inline fn value(_: *const ZoneContext, _: u64) void {}
};
pub inline fn initZone(comptime src: std.builtin.SourceLocation, comptime opts: ZoneOptions) ZoneContext {
if (!options.tracy_enable) return .{};
const active: c_int = @intFromBool(opts.active);
const static = struct {
var src_loc = c.___tracy_source_location_data{
.name = if (opts.name) |name| name.ptr else null,
.function = src.fn_name.ptr,
.file = src.file,
.line = 0,
.color = opts.color orelse 0,
};
};
// src.line magically is not comptime https://github.com/ziglang/zig/pull/12016#issuecomment-1178092847
static.src_loc.line = src.line;
if (!options.tracy_no_callstack) {
if (options.tracy_callstack) |depth| {
return .{
.ctx = c.___tracy_emit_zone_begin_callstack(&static.src_loc, depth, active),
};
}
}
return .{
.ctx = c.___tracy_emit_zone_begin(&static.src_loc, active),
};
}
pub inline fn plot(comptime T: type, comptime name: [:0]const u8, value: T) void {
if (!options.tracy_enable) return;
const type_info = @typeInfo(T);
switch (type_info) {
.int => |int_type| {
if (int_type.bits > 64) @compileError("Too large int to plot");
if (int_type.signedness == .unsigned and int_type.bits > 63) @compileError("Too large unsigned int to plot");
c.___tracy_emit_plot_int(name, value);
},
.float => |float_type| {
if (float_type.bits <= 32) {
c.___tracy_emit_plot_float(name, value);
} else if (float_type.bits <= 64) {
c.___tracy_emit_plot(name, value);
} else {
@compileError("Too large float to plot");
}
},
else => @compileError("Unsupported plot value type"),
}
}
pub const PlotType = enum(c_int) {
Number,
Memory,
Percentage,
Watt,
};
pub const PlotConfig = struct {
plot_type: PlotType,
step: c_int,
fill: c_int,
color: u32,
};
pub inline fn plotConfig(comptime name: [:0]const u8, comptime config: PlotConfig) void {
if (!options.tracy_enable) return;
c.___tracy_emit_plot_config(
name,
@intFromEnum(config.plot_type),
config.step,
config.fill,
config.color,
);
}
pub inline fn message(comptime msg: [:0]const u8) void {
if (!options.tracy_enable) return;
const depth = options.tracy_callstack orelse 0;
c.___tracy_emit_messageL(msg, depth);
}
pub inline fn messageColor(comptime msg: [:0]const u8, color: u32) void {
if (!options.tracy_enable) return;
const depth = options.tracy_callstack orelse 0;
c.___tracy_emit_messageLC(msg, color, depth);
}
const tracy_message_buffer_size = if (options.tracy_enable) 4096 else 0;
threadlocal var tracy_message_buffer: [tracy_message_buffer_size]u8 = undefined;
pub inline fn print(comptime fmt: []const u8, args: anytype) void {
if (!options.tracy_enable) return;
const depth = options.tracy_callstack orelse 0;
var stream = std.io.fixedBufferStream(&tracy_message_buffer);
stream.writer().print(fmt, args) catch {};
const written = stream.getWritten();
c.___tracy_emit_message(written.ptr, written.len, depth);
}
pub inline fn printColor(comptime fmt: []const u8, args: anytype, color: u32) void {
if (!options.tracy_enable) return;
const depth = options.tracy_callstack orelse 0;
var stream = std.io.fixedBufferStream(&tracy_message_buffer);
stream.writer().print(fmt, args) catch {};
const written = stream.getWritten();
c.___tracy_emit_messageC(written.ptr, written.len, color, depth);
}
pub inline fn printAppInfo(comptime fmt: []const u8, args: anytype) void {
if (!options.tracy_enable) return;
var stream = std.io.fixedBufferStream(&tracy_message_buffer);
stream.reset();
stream.writer().print(fmt, args) catch {};
const written = stream.getWritten();
c.___tracy_emit_message_appinfo(written.ptr, written.len);
}
pub const TracingAllocator = struct {
parent_allocator: std.mem.Allocator,
pool_name: ?[:0]const u8,
const Self = @This();
pub fn init(parent_allocator: std.mem.Allocator) Self {
return .{
.parent_allocator = parent_allocator,
.pool_name = null,
};
}
pub fn initNamed(comptime pool_name: [:0]const u8, parent_allocator: std.mem.Allocator) Self {
return .{
.parent_allocator = parent_allocator,
.pool_name = pool_name,
};
}
pub fn allocator(self: *Self) std.mem.Allocator {
return .{
.ptr = self,
.vtable = &.{
.alloc = alloc,
.resize = resize,
.remap = remap,
.free = free,
},
};
}
fn alloc(
ctx: *anyopaque,
len: usize,
ptr_align: std.mem.Alignment,
ret_addr: usize,
) ?[*]u8 {
const self: *Self = @ptrCast(@alignCast(ctx));
const result = self.parent_allocator.rawAlloc(len, ptr_align, ret_addr);
if (!options.tracy_enable) return result;
if (self.pool_name) |name| {
c.___tracy_emit_memory_alloc_named(result, len, 0, name.ptr);
} else {
c.___tracy_emit_memory_alloc(result, len, 0);
}
return result;
}
fn resize(
ctx: *anyopaque,
buf: []u8,
buf_align: std.mem.Alignment,
new_len: usize,
ret_addr: usize,
) bool {
const self: *Self = @ptrCast(@alignCast(ctx));
const result = self.parent_allocator.rawResize(buf, buf_align, new_len, ret_addr);
if (!result) return false;
if (!options.tracy_enable) return true;
if (self.pool_name) |name| {
c.___tracy_emit_memory_free_named(buf.ptr, 0, name.ptr);
c.___tracy_emit_memory_alloc_named(buf.ptr, new_len, 0, name.ptr);
} else {
c.___tracy_emit_memory_free(buf.ptr, 0);
c.___tracy_emit_memory_alloc(buf.ptr, new_len, 0);
}
return true;
}
fn remap(
ctx: *anyopaque,
buf: []u8,
buf_align: std.mem.Alignment,
new_len: usize,
ret_addr: usize,
) ?[*]u8 {
const self: *Self = @ptrCast(@alignCast(ctx));
const result = self.parent_allocator.rawRemap(buf, buf_align, new_len, ret_addr);
const new_buf = result orelse return null;
if (!options.tracy_enable) return new_buf;
if (self.pool_name) |name| {
c.___tracy_emit_memory_free_named(buf.ptr, 0, name.ptr);
c.___tracy_emit_memory_alloc_named(new_buf, new_len, 0, name.ptr);
} else {
c.___tracy_emit_memory_free(buf.ptr, 0);
c.___tracy_emit_memory_alloc(new_buf, new_len, 0);
}
return new_buf;
}
fn free(
ctx: *anyopaque,
buf: []u8,
buf_align: std.mem.Alignment,
ret_addr: usize,
) void {
const self: *Self = @ptrCast(@alignCast(ctx));
if (options.tracy_enable) {
if (self.pool_name) |name| {
c.___tracy_emit_memory_free_named(buf.ptr, 0, name.ptr);
} else {
c.___tracy_emit_memory_free(buf.ptr, 0);
}
}
self.parent_allocator.rawFree(buf, buf_align, ret_addr);
}
};