mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
integrate tracy more deeply
This commit is contained in:
13
src/App.zig
13
src/App.zig
@ -8,6 +8,7 @@ const Allocator = std.mem.Allocator;
|
|||||||
const glfw = @import("glfw");
|
const glfw = @import("glfw");
|
||||||
const Window = @import("Window.zig");
|
const Window = @import("Window.zig");
|
||||||
const libuv = @import("libuv/main.zig");
|
const libuv = @import("libuv/main.zig");
|
||||||
|
const tracy = @import("tracy/tracy.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.app);
|
const log = std.log.scoped(.app);
|
||||||
|
|
||||||
@ -84,7 +85,15 @@ pub fn run(self: App) !void {
|
|||||||
}).callback);
|
}).callback);
|
||||||
|
|
||||||
while (!self.window.shouldClose()) {
|
while (!self.window.shouldClose()) {
|
||||||
try self.window.run();
|
// Mark this so we're in a totally different "frame"
|
||||||
|
tracy.frameMark();
|
||||||
|
|
||||||
|
// Track the render part of the frame separately.
|
||||||
|
{
|
||||||
|
const frame = tracy.frame("render");
|
||||||
|
defer frame.end();
|
||||||
|
try self.window.run();
|
||||||
|
}
|
||||||
|
|
||||||
// Block for any glfw events. This may also be an "empty" event
|
// Block for any glfw events. This may also be an "empty" event
|
||||||
// posted by the libuv watcher so that we trigger a libuv loop tick.
|
// posted by the libuv watcher so that we trigger a libuv loop tick.
|
||||||
@ -103,6 +112,8 @@ pub fn run(self: App) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run the libuv loop
|
// Run the libuv loop
|
||||||
|
const frame = tracy.frame("libuv");
|
||||||
|
defer frame.end();
|
||||||
try embed.loopRun();
|
try embed.loopRun();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ const FontAtlas = @import("FontAtlas.zig");
|
|||||||
const Terminal = @import("terminal/Terminal.zig");
|
const Terminal = @import("terminal/Terminal.zig");
|
||||||
const gl = @import("opengl.zig");
|
const gl = @import("opengl.zig");
|
||||||
const gb = @import("gb_math.zig");
|
const gb = @import("gb_math.zig");
|
||||||
|
const trace = @import("tracy/tracy.zig").trace;
|
||||||
|
|
||||||
const log = std.log.scoped(.grid);
|
const log = std.log.scoped(.grid);
|
||||||
|
|
||||||
@ -343,6 +344,9 @@ pub fn setScreenSize(self: *Grid, dim: ScreenSize) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(self: Grid) !void {
|
pub fn render(self: Grid) !void {
|
||||||
|
const t = trace(@src());
|
||||||
|
defer t.end();
|
||||||
|
|
||||||
// If we have no cells to render, then we render nothing.
|
// If we have no cells to render, then we render nothing.
|
||||||
if (self.cells.items.len == 0) return;
|
if (self.cells.items.len == 0) return;
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ const Pty = @import("Pty.zig");
|
|||||||
const Command = @import("Command.zig");
|
const Command = @import("Command.zig");
|
||||||
const Terminal = @import("terminal/Terminal.zig");
|
const Terminal = @import("terminal/Terminal.zig");
|
||||||
const SegmentedPool = @import("segmented_pool.zig").SegmentedPool;
|
const SegmentedPool = @import("segmented_pool.zig").SegmentedPool;
|
||||||
|
const trace = @import("tracy/tracy.zig").trace;
|
||||||
|
|
||||||
const log = std.log.scoped(.window);
|
const log = std.log.scoped(.window);
|
||||||
|
|
||||||
@ -231,6 +232,9 @@ pub fn shouldClose(self: Window) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(self: Window) !void {
|
pub fn run(self: Window) !void {
|
||||||
|
const tracy = trace(@src());
|
||||||
|
defer tracy.end();
|
||||||
|
|
||||||
// Set our background
|
// Set our background
|
||||||
gl.clearColor(0.2, 0.3, 0.3, 1.0);
|
gl.clearColor(0.2, 0.3, 0.3, 1.0);
|
||||||
gl.clear(gl.c.GL_COLOR_BUFFER_BIT);
|
gl.clear(gl.c.GL_COLOR_BUFFER_BIT);
|
||||||
@ -243,6 +247,9 @@ pub fn run(self: Window) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn sizeCallback(window: glfw.Window, width: i32, height: i32) void {
|
fn sizeCallback(window: glfw.Window, width: i32, height: i32) void {
|
||||||
|
const tracy = trace(@src());
|
||||||
|
defer tracy.end();
|
||||||
|
|
||||||
// glfw gives us signed integers, but negative width/height is n
|
// glfw gives us signed integers, but negative width/height is n
|
||||||
// non-sensical so we use unsigned throughout, so assert.
|
// non-sensical so we use unsigned throughout, so assert.
|
||||||
assert(width >= 0);
|
assert(width >= 0);
|
||||||
@ -279,6 +286,9 @@ fn sizeCallback(window: glfw.Window, width: i32, height: i32) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn charCallback(window: glfw.Window, codepoint: u21) void {
|
fn charCallback(window: glfw.Window, codepoint: u21) void {
|
||||||
|
const tracy = trace(@src());
|
||||||
|
defer tracy.end();
|
||||||
|
|
||||||
const win = window.getUserPointer(Window) orelse return;
|
const win = window.getUserPointer(Window) orelse return;
|
||||||
|
|
||||||
// Write the character to the pty
|
// Write the character to the pty
|
||||||
@ -299,6 +309,9 @@ fn keyCallback(
|
|||||||
action: glfw.Action,
|
action: glfw.Action,
|
||||||
mods: glfw.Mods,
|
mods: glfw.Mods,
|
||||||
) void {
|
) void {
|
||||||
|
const tracy = trace(@src());
|
||||||
|
defer tracy.end();
|
||||||
|
|
||||||
_ = scancode;
|
_ = scancode;
|
||||||
_ = mods;
|
_ = mods;
|
||||||
|
|
||||||
@ -352,6 +365,9 @@ fn keyCallback(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn focusCallback(window: glfw.Window, focused: bool) void {
|
fn focusCallback(window: glfw.Window, focused: bool) void {
|
||||||
|
const tracy = trace(@src());
|
||||||
|
defer tracy.end();
|
||||||
|
|
||||||
const win = window.getUserPointer(Window) orelse return;
|
const win = window.getUserPointer(Window) orelse return;
|
||||||
if (focused) {
|
if (focused) {
|
||||||
win.wakeup = true;
|
win.wakeup = true;
|
||||||
@ -367,17 +383,27 @@ fn focusCallback(window: glfw.Window, focused: bool) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn cursorTimerCallback(t: *libuv.Timer) void {
|
fn cursorTimerCallback(t: *libuv.Timer) void {
|
||||||
|
const tracy = trace(@src());
|
||||||
|
defer tracy.end();
|
||||||
|
|
||||||
const win = t.getData(Window) orelse return;
|
const win = t.getData(Window) orelse return;
|
||||||
win.grid.cursor_visible = !win.grid.cursor_visible;
|
win.grid.cursor_visible = !win.grid.cursor_visible;
|
||||||
win.grid.updateCells(win.terminal) catch unreachable;
|
win.grid.updateCells(win.terminal) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ttyReadAlloc(t: *libuv.Tty, size: usize) ?[]u8 {
|
fn ttyReadAlloc(t: *libuv.Tty, size: usize) ?[]u8 {
|
||||||
|
const tracy = trace(@src());
|
||||||
|
defer tracy.end();
|
||||||
|
|
||||||
const alloc = t.loop().getData(Allocator).?.*;
|
const alloc = t.loop().getData(Allocator).?.*;
|
||||||
return alloc.alloc(u8, size) catch null;
|
return alloc.alloc(u8, size) catch null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ttyRead(t: *libuv.Tty, n: isize, buf: []const u8) void {
|
fn ttyRead(t: *libuv.Tty, n: isize, buf: []const u8) void {
|
||||||
|
const tracy = trace(@src());
|
||||||
|
tracy.color(0xEAEA7F); // yellow-ish
|
||||||
|
defer tracy.end();
|
||||||
|
|
||||||
const win = t.getData(Window).?;
|
const win = t.getData(Window).?;
|
||||||
defer win.alloc.free(buf);
|
defer win.alloc.free(buf);
|
||||||
|
|
||||||
@ -411,6 +437,9 @@ fn ttyRead(t: *libuv.Tty, n: isize, buf: []const u8) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ttyWrite(req: *libuv.WriteReq, status: i32) void {
|
fn ttyWrite(req: *libuv.WriteReq, status: i32) void {
|
||||||
|
const tracy = trace(@src());
|
||||||
|
defer tracy.end();
|
||||||
|
|
||||||
const tty = req.handle(libuv.Tty).?;
|
const tty = req.handle(libuv.Tty).?;
|
||||||
const win = tty.getData(Window).?;
|
const win = tty.getData(Window).?;
|
||||||
win.write_req_pool.put();
|
win.write_req_pool.put();
|
||||||
|
@ -6,9 +6,6 @@ const App = @import("App.zig");
|
|||||||
const trace = @import("tracy/tracy.zig").trace;
|
const trace = @import("tracy/tracy.zig").trace;
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
const tracy = trace(@src());
|
|
||||||
defer tracy.end();
|
|
||||||
|
|
||||||
var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
|
var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
const gpa = general_purpose_allocator.allocator();
|
const gpa = general_purpose_allocator.allocator();
|
||||||
defer _ = general_purpose_allocator.deinit();
|
defer _ = general_purpose_allocator.deinit();
|
||||||
|
@ -22,28 +22,52 @@ const Impl = struct {
|
|||||||
const has_callstack_support = @hasDecl(c, "TRACY_HAS_CALLSTACK") and @hasDecl(c, "TRACY_CALLSTACK");
|
const has_callstack_support = @hasDecl(c, "TRACY_HAS_CALLSTACK") and @hasDecl(c, "TRACY_CALLSTACK");
|
||||||
const callstack_enabled: c_int = if (has_callstack_support) c.TRACY_CALLSTACK else 0;
|
const callstack_enabled: c_int = if (has_callstack_support) c.TRACY_CALLSTACK else 0;
|
||||||
|
|
||||||
pub const ZoneCtx = struct {
|
/// A zone represents the lifetime of a special on-stack profiler variable.
|
||||||
|
/// Typically it would exist for the duration of a whole scope of the
|
||||||
|
/// profiled function, but you also can measure time spent in scopes of a
|
||||||
|
/// for-loop or an if-branch.
|
||||||
|
pub const Zone = struct {
|
||||||
zone: c.___tracy_c_zone_context,
|
zone: c.___tracy_c_zone_context,
|
||||||
|
|
||||||
pub inline fn text(self: ZoneCtx, val: []const u8) void {
|
/// Text description of a zone.
|
||||||
|
pub inline fn text(self: Zone, val: []const u8) void {
|
||||||
c.___tracy_emit_zone_text(self.zone, val.ptr, val.len);
|
c.___tracy_emit_zone_text(self.zone, val.ptr, val.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn name(self: ZoneCtx, val: []const u8) void {
|
/// Name of the zone.
|
||||||
|
pub inline fn name(self: Zone, val: []const u8) void {
|
||||||
c.___tracy_emit_zone_name(self.zone, val.ptr, val.len);
|
c.___tracy_emit_zone_name(self.zone, val.ptr, val.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn value(self: ZoneCtx, val: u64) void {
|
/// Color of the zone in the UI. Specify the value as RGB
|
||||||
|
/// using hex: 0xRRGGBB.
|
||||||
|
pub inline fn color(self: Zone, val: u32) void {
|
||||||
|
c.___tracy_emit_zone_color(self.zone, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A value associated with the zone.
|
||||||
|
pub inline fn value(self: Zone, val: u64) void {
|
||||||
c.___tracy_emit_zone_value(self.zone, val);
|
c.___tracy_emit_zone_value(self.zone, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn end(self: ZoneCtx) void {
|
/// End the zone.
|
||||||
|
pub inline fn end(self: Zone) void {
|
||||||
c.___tracy_emit_zone_end(self.zone);
|
c.___tracy_emit_zone_end(self.zone);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Tracy profiles within the context of a frame. This represents
|
||||||
|
/// a single frame.
|
||||||
|
pub fn Frame(comptime name: [:0]const u8) type {
|
||||||
|
return struct {
|
||||||
|
pub fn end(_: @This()) void {
|
||||||
|
c.___tracy_emit_frame_mark_end(name.ptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Start a trace. Defer calling end() to end the trace.
|
/// Start a trace. Defer calling end() to end the trace.
|
||||||
pub inline fn trace(comptime src: SourceLocation) ZoneCtx {
|
pub inline fn trace(comptime src: SourceLocation) Zone {
|
||||||
const callstack_depth = 10; // TODO configurable
|
const callstack_depth = 10; // TODO configurable
|
||||||
|
|
||||||
const static = struct {
|
const static = struct {
|
||||||
@ -62,20 +86,45 @@ const Impl = struct {
|
|||||||
else
|
else
|
||||||
c.___tracy_emit_zone_begin(&static.loc, 1);
|
c.___tracy_emit_zone_begin(&static.loc, 1);
|
||||||
|
|
||||||
return ZoneCtx{ .zone = zone };
|
return Zone{ .zone = zone };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mark the boundary of a frame. Good for continuous frames. For
|
||||||
|
/// discontinous frames, use frame() and defer end().
|
||||||
|
pub inline fn frameMark() void {
|
||||||
|
c.___tracy_emit_frame_mark(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start a discontinuous frame.
|
||||||
|
pub inline fn frame(comptime name: [:0]const u8) Frame(name) {
|
||||||
|
c.___tracy_emit_frame_mark_start(name.ptr);
|
||||||
|
return .{};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const Noop = struct {
|
const Noop = struct {
|
||||||
pub const ZoneCtx = struct {
|
pub const Zone = struct {
|
||||||
pub inline fn text(_: ZoneCtx, _: []const u8) void {}
|
pub inline fn text(_: Zone, _: []const u8) void {}
|
||||||
pub inline fn name(_: ZoneCtx, _: []const u8) void {}
|
pub inline fn name(_: Zone, _: []const u8) void {}
|
||||||
pub inline fn value(_: ZoneCtx, _: u64) void {}
|
pub inline fn color(_: Zone, _: u32) void {}
|
||||||
pub inline fn end(_: ZoneCtx) void {}
|
pub inline fn value(_: Zone, _: u64) void {}
|
||||||
|
pub inline fn end(_: Zone) void {}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub inline fn trace(comptime src: SourceLocation) ZoneCtx {
|
pub fn Frame(comptime _: [:0]const u8) type {
|
||||||
|
return struct {
|
||||||
|
pub fn end(_: @This()) void {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn trace(comptime src: SourceLocation) Zone {
|
||||||
_ = src;
|
_ = src;
|
||||||
return .{};
|
return .{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn frameMark() void {}
|
||||||
|
|
||||||
|
pub inline fn frame(comptime name: [*:0]const u8) Frame(name) {
|
||||||
|
return .{};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user