Files
Renderive/Kernel/src/renderive/scene/base/Abstract_Frame.cpp
T

106 lines
3.4 KiB
C++

#include "Abstract_Frame.hpp"
#include <chrono>
#include <stdexcept>
void Node_Execution_Metrics::set(Node_Metric_Kind kind, std::uint64_t value) noexcept {
const auto index = static_cast<std::size_t>(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<std::size_t>(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<std::size_t>(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<const Frame_Snapshot> 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<Frame_Snapshot>();
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<const Frame_Snapshot> Abstract_Frame::completed_snapshot() const noexcept {
return completed_snapshot_;
}
std::uint64_t render_clock_now_ns() noexcept {
return static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::steady_clock::now().time_since_epoch()).count());
}