#include "Abstract_Frame.hpp" #include #include void Node_Execution_Metrics::set(Node_Metric_Kind kind, std::uint64_t value) noexcept { const auto index = static_cast(kind); if (index >= values.size()) return; values[index] = value; present |= std::uint32_t{1} << index; } bool Node_Execution_Metrics::contains(Node_Metric_Kind kind) const noexcept { const auto index = static_cast(kind); return index < values.size() && (present & (std::uint32_t{1} << index)) != 0; } std::uint64_t Node_Execution_Metrics::get(Node_Metric_Kind kind) const noexcept { return contains(kind) ? values[static_cast(kind)] : 0; } std::uint64_t Node_Execution::duration_ns() const noexcept { return end_time_ns >= start_time_ns ? end_time_ns - start_time_ns : 0; } std::uint64_t Node_Execution::cpu_duration_ns() const noexcept { return cpu_end_time_ns >= start_time_ns ? cpu_end_time_ns - start_time_ns : 0; } std::uint64_t Node_Execution::external_duration_ns() const noexcept { return external_end_time_ns >= external_start_time_ns ? external_end_time_ns - external_start_time_ns : 0; } std::uint64_t Frame_Snapshot::render_duration_ns() const noexcept { return render_end_ns >= render_start_ns ? render_end_ns - render_start_ns : 0; } void Abstract_Frame::begin_render(std::uint64_t frame_id, const Render_Plan& plan, bool capture, std::uint64_t render_start_ns) { if (rendering_) throw std::logic_error("frame render is already active"); rendering_ = true; capture_ = capture; frame_id_ = frame_id; plan_version_ = plan.version; render_start_ns_ = render_start_ns; completed_snapshot_.reset(); executions_.clear(); if (!capture) return; executions_.resize(plan.graph.nodes.size()); for (const auto& node : plan.graph.nodes) executions_.at(node.execution_index).node_id = node.node_id; } bool Abstract_Frame::capture_this_frame() const noexcept { return rendering_ && capture_; } Node_Execution* Abstract_Frame::execution_slot(std::size_t index) noexcept { return capture_this_frame() && index < executions_.size() ? &executions_[index] : nullptr; } std::shared_ptr Abstract_Frame::complete_render( std::uint64_t render_end_ns) { if (!rendering_) throw std::logic_error("frame render is not active"); rendering_ = false; if (!capture_) { capture_ = false; return nullptr; } auto snapshot = std::make_shared(); snapshot->frame_id = frame_id_; snapshot->render_plan_version = plan_version_; snapshot->render_start_ns = render_start_ns_; snapshot->render_end_ns = render_end_ns; snapshot->node_executions = std::move(executions_); completed_snapshot_ = snapshot; capture_ = false; return snapshot; } void Abstract_Frame::discard_render() noexcept { rendering_ = false; capture_ = false; frame_id_ = 0; plan_version_ = 0; render_start_ns_ = 0; executions_.clear(); completed_snapshot_.reset(); } std::shared_ptr Abstract_Frame::completed_snapshot() const noexcept { return completed_snapshot_; } std::uint64_t render_clock_now_ns() noexcept { return static_cast(std::chrono::duration_cast( std::chrono::steady_clock::now().time_since_epoch()).count()); }