статистика времени кадра
This commit is contained in:
@@ -24,17 +24,20 @@ scroll: dvui.ScrollInfo = .{
|
||||
.horizontal = .auto,
|
||||
},
|
||||
native_scaling: bool = true,
|
||||
redraw_throttle_ms: u32 = 50,
|
||||
_visible_rect: ?Rect_i = null,
|
||||
_zoom: f32 = 1,
|
||||
_redraw_pending: bool = false,
|
||||
_last_redraw_time_ms: i64 = 0,
|
||||
cursor_document_point: ?Point2_f = null,
|
||||
draw_document: bool = true,
|
||||
show_render_stats: bool = true,
|
||||
/// Rect тулбара (из предыдущего кадра) для исключения кликов по нему из handleCanvasMouse.
|
||||
toolbar_rect_scale: ?dvui.RectScale = null,
|
||||
/// Rect панели свойств (из предыдущего кадра) для исключения кликов по нему из handleCanvasMouse.
|
||||
properties_rect_scale: ?dvui.RectScale = null,
|
||||
redraw_throttle_ms: u32 = 50,
|
||||
frame_index: u64 = 0,
|
||||
|
||||
_zoom: f32 = 1,
|
||||
_last_redraw_time_ms: i64 = 0, // Метка последней перерисовки чтобы ограничить частоту
|
||||
_visible_rect: ?Rect_i = null,
|
||||
_redraw_pending: bool = false,
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator, document: *Document, engine: RenderEngine) Canvas {
|
||||
return .{
|
||||
@@ -80,6 +83,7 @@ fn redraw(self: *Canvas) !void {
|
||||
self.texture = tex;
|
||||
}
|
||||
self._last_redraw_time_ms = std.time.milliTimestamp();
|
||||
self.frame_index += 1;
|
||||
}
|
||||
|
||||
pub fn exampleReset(self: *Canvas) !void {
|
||||
|
||||
@@ -45,17 +45,14 @@ pub const OpenDocument = struct {
|
||||
};
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
frame_index: u64,
|
||||
documents: std.ArrayList(*OpenDocument),
|
||||
active_document_index: ?usize,
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !WindowContext {
|
||||
const frame_index: u64 = 0;
|
||||
const documents = std.ArrayList(*OpenDocument).empty;
|
||||
const active_document_index: ?usize = null;
|
||||
return .{
|
||||
.allocator = allocator,
|
||||
.frame_index = frame_index,
|
||||
.documents = documents,
|
||||
.active_document_index = active_document_index,
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ const RenderEngine = @import("RenderEngine.zig").RenderEngine;
|
||||
const Document = @import("../models/Document.zig");
|
||||
const basic_models = @import("../models/basic_models.zig");
|
||||
const cpu_draw = @import("cpu/draw.zig");
|
||||
const RenderStats = @import("RenderStats.zig");
|
||||
const Size_i = basic_models.Size_i;
|
||||
const Rect_i = basic_models.Rect_i;
|
||||
const Allocator = std.mem.Allocator;
|
||||
@@ -17,14 +18,18 @@ const Type = enum {
|
||||
};
|
||||
|
||||
type: Type,
|
||||
_allocator: Allocator,
|
||||
gradient_start: Color.PMA = .{ .r = 0, .g = 0, .b = 0, .a = 255 },
|
||||
gradient_end: Color.PMA = .{ .r = 255, .g = 255, .b = 255, .a = 255 },
|
||||
_allocator: Allocator,
|
||||
_renderStats: RenderStats,
|
||||
|
||||
pub fn init(allocator: Allocator, render_type: Type) CpuRenderEngine {
|
||||
return .{
|
||||
._allocator = allocator,
|
||||
.type = render_type,
|
||||
._renderStats = .{
|
||||
.render_time_ns = 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -182,7 +187,13 @@ pub fn renderDocument(self: *CpuRenderEngine, document: *const Document, canvas_
|
||||
defer self._allocator.free(pixels);
|
||||
|
||||
for (pixels) |*p| p.* = .{ .r = 255, .g = 255, .b = 255, .a = 255 };
|
||||
var t = try std.time.Timer.start();
|
||||
try cpu_draw.drawDocument(pixels, width, height, visible_rect, document, canvas_size, self._allocator);
|
||||
self._renderStats.render_time_ns = t.read();
|
||||
|
||||
return try dvui.textureCreate(pixels, width, height, .nearest);
|
||||
}
|
||||
|
||||
pub fn getStats(self: CpuRenderEngine) RenderStats {
|
||||
return self._renderStats;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ const dvui = @import("dvui");
|
||||
const CpuRenderEngine = @import("CpuRenderEngine.zig");
|
||||
const Document = @import("../models/Document.zig");
|
||||
const basic_models = @import("../models/basic_models.zig");
|
||||
const RenderStats = @import("RenderStats.zig");
|
||||
|
||||
pub const RenderEngine = union(enum) {
|
||||
cpu: *CpuRenderEngine,
|
||||
@@ -18,6 +19,12 @@ pub const RenderEngine = union(enum) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getStats(self: RenderEngine) RenderStats {
|
||||
return switch (self) {
|
||||
.cpu => |cpu_r| cpu_r.getStats(),
|
||||
};
|
||||
}
|
||||
|
||||
/// Растеризует документ в текстуру.
|
||||
pub fn render(self: RenderEngine, document: *const Document, canvas_size: basic_models.Size_i, visible_rect: basic_models.Rect_i) !?dvui.Texture {
|
||||
return switch (self) {
|
||||
|
||||
3
src/render/RenderStats.zig
Normal file
3
src/render/RenderStats.zig
Normal file
@@ -0,0 +1,3 @@
|
||||
const RenderStats = @This();
|
||||
|
||||
render_time_ns: u64, // Время рендера кадра в микросекундах
|
||||
@@ -7,6 +7,7 @@ const Property = @import("../models/Property.zig").Property;
|
||||
const PropertyData = @import("../models/Property.zig").Data;
|
||||
const Rect_i = @import("../models/basic_models.zig").Rect_i;
|
||||
const Tool = @import("../toolbar/Tool.zig");
|
||||
const RenderStats = @import("../render/RenderStats.zig");
|
||||
|
||||
pub fn canvasView(canvas: *Canvas, selected_object_id: ?u64, content_rect_scale: dvui.RectScale) void {
|
||||
var textured = dvui_ext.texturedBox(content_rect_scale, dvui.Rect.all(20));
|
||||
@@ -36,23 +37,27 @@ pub fn canvasView(canvas: *Canvas, selected_object_id: ?u64, content_rect_scale:
|
||||
const scroll_parent = dvui.parentGet();
|
||||
dvui.parentSet(overlay_parent);
|
||||
|
||||
const vbar = scroll.vbar;
|
||||
const hbar = scroll.hbar;
|
||||
if (vbar != null) {
|
||||
|
||||
// std.debug.print("{any}", .{vbar.?.data()});
|
||||
}
|
||||
if (hbar != null) {
|
||||
// std.debug.print("{any}", .{hbar.?.data()});
|
||||
}
|
||||
|
||||
// Тулбар поверх scroll
|
||||
var toolbar_box = dvui.box(
|
||||
@src(),
|
||||
.{ .dir = .horizontal },
|
||||
.{
|
||||
.expand = .none,
|
||||
.background = false,
|
||||
.gravity_x = 0.0,
|
||||
.gravity_y = 0.0,
|
||||
.margin = dvui.Rect{ .x = 16, .y = 16 },
|
||||
},
|
||||
.{},
|
||||
);
|
||||
{
|
||||
drawToolbar(canvas);
|
||||
}
|
||||
// Сохраняем rect тулбара для следующего кадра — в handleCanvasMouse исключаем из него клики
|
||||
canvas.toolbar_rect_scale = toolbar_box.data().contentRectScale();
|
||||
}
|
||||
toolbar_box.deinit();
|
||||
|
||||
// Панель свойств поверх scroll (правый верхний угол)
|
||||
@@ -61,24 +66,20 @@ pub fn canvasView(canvas: *Canvas, selected_object_id: ?u64, content_rect_scale:
|
||||
var properties_box = dvui.box(
|
||||
@src(),
|
||||
.{ .dir = .horizontal },
|
||||
.{
|
||||
.expand = .none,
|
||||
.background = false,
|
||||
.gravity_x = 1.0,
|
||||
.gravity_y = 0.0,
|
||||
.margin = dvui.Rect{ .w = 32, .y = 16, .h = 100 },
|
||||
},
|
||||
.{},
|
||||
);
|
||||
{
|
||||
drawPropertiesPanel(canvas, obj);
|
||||
}
|
||||
// Сохраняем rect панели свойств для следующего кадра — в handleCanvasMouse исключаем из него клики
|
||||
canvas.properties_rect_scale = properties_box.data().contentRectScale();
|
||||
}
|
||||
properties_box.deinit();
|
||||
}
|
||||
}
|
||||
|
||||
dvui.label(@src(), "Canvas", .{}, .{ .gravity_x = 0.5, .gravity_y = 0.0 });
|
||||
drawCanvasLabelPanel();
|
||||
if (canvas.show_render_stats)
|
||||
drawStatsPanel(canvas.render_engine.getStats(), canvas.frame_index);
|
||||
|
||||
if (canvas.properties_rect_scale) |prs| {
|
||||
for (dvui.events()) |*e| {
|
||||
@@ -278,6 +279,7 @@ fn drawToolbar(canvas: *Canvas) void {
|
||||
.corner_radius = dvui.Rect.all(8),
|
||||
.background = true,
|
||||
.color_fill = dvui.Color.black.opacity(0.2),
|
||||
.margin = dvui.Rect{ .x = 16, .y = 16 },
|
||||
},
|
||||
);
|
||||
{
|
||||
@@ -312,6 +314,7 @@ fn drawPropertiesPanel(canvas: *Canvas, selected_object: *Document.Object) void
|
||||
.background = true,
|
||||
.color_fill = dvui.Color.black.opacity(0.2),
|
||||
.min_size_content = .{ .w = 220 },
|
||||
.margin = dvui.Rect{ .w = 32, .y = 16, .h = 100 },
|
||||
},
|
||||
);
|
||||
{
|
||||
@@ -332,6 +335,47 @@ fn drawPropertiesPanel(canvas: *Canvas, selected_object: *Document.Object) void
|
||||
panel.deinit();
|
||||
}
|
||||
|
||||
fn drawCanvasLabelPanel() void {
|
||||
var panel = dvui.box(
|
||||
@src(),
|
||||
.{ .dir = .vertical },
|
||||
.{
|
||||
.gravity_x = 0.5,
|
||||
.gravity_y = 0.0,
|
||||
.padding = dvui.Rect.all(8),
|
||||
.corner_radius = dvui.Rect.all(8),
|
||||
.background = true,
|
||||
.color_fill = dvui.Color.black.opacity(0.2),
|
||||
.margin = dvui.Rect{ .x = 16, .y = 16 },
|
||||
},
|
||||
);
|
||||
{
|
||||
dvui.label(@src(), "Canvas", .{}, .{});
|
||||
}
|
||||
panel.deinit();
|
||||
}
|
||||
|
||||
fn drawStatsPanel(stats: RenderStats, frame_index: u64) void {
|
||||
var panel = dvui.box(
|
||||
@src(),
|
||||
.{ .dir = .vertical },
|
||||
.{
|
||||
.gravity_x = 0.0,
|
||||
.gravity_y = 1.0,
|
||||
.padding = dvui.Rect.all(8),
|
||||
.corner_radius = dvui.Rect.all(8),
|
||||
.background = true,
|
||||
.color_fill = dvui.Color.black.opacity(0.2),
|
||||
.margin = dvui.Rect{ .x = 16, .h = 16 },
|
||||
},
|
||||
);
|
||||
{
|
||||
dvui.label(@src(), "Frame time: {}ms", .{stats.render_time_ns / std.time.ns_per_ms}, .{});
|
||||
dvui.label(@src(), "Frame index: {}", .{frame_index}, .{});
|
||||
}
|
||||
panel.deinit();
|
||||
}
|
||||
|
||||
fn drawPropertyEditor(canvas: *Canvas, obj: *Document.Object, prop: *const Property, row_index: usize) void {
|
||||
const row_id: usize = row_index * 16;
|
||||
var row = dvui.box(
|
||||
|
||||
@@ -30,6 +30,5 @@ pub fn guiFrame(ctx: *WindowContext) bool {
|
||||
}
|
||||
root.deinit();
|
||||
|
||||
ctx.frame_index += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -175,6 +175,7 @@ pub fn leftPanel(ctx: *WindowContext) void {
|
||||
if (dvui.checkbox(@src(), &canvas.draw_document, "Draw document", .{})) {
|
||||
canvas.requestRedraw();
|
||||
}
|
||||
if (dvui.checkbox(@src(), &canvas.show_render_stats, "Show stats", .{})) {}
|
||||
if (!canvas.draw_document) {
|
||||
if (dvui.button(@src(), if (doc.cpu_render.type == .Gradient) "Gradient" else "Squares", .{}, .{})) {
|
||||
if (doc.cpu_render.type == .Gradient) {
|
||||
@@ -188,6 +189,9 @@ pub fn leftPanel(ctx: *WindowContext) void {
|
||||
if (dvui.button(@src(), "Add random shapes", .{}, .{})) {
|
||||
canvas.addRandomShapes() catch {};
|
||||
}
|
||||
if (dvui.button(@src(), "Request redraw", .{}, .{})) {
|
||||
canvas.requestRedraw();
|
||||
}
|
||||
} else {
|
||||
dvui.label(@src(), "No document", .{}, .{});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user