延迟低了很多

This commit is contained in:
2026-08-24 17:28:17 +08:00
parent f463a756fc
commit c0d5a13350
14 changed files with 335 additions and 162 deletions
+43
View File
@@ -0,0 +1,43 @@
#include "event.hpp"
#include <stdexcept>
namespace aethera {
Event_Statistics_Accumulator::Event_Statistics_Accumulator(
std::size_t capacity) {
if (capacity == 0)
throw std::invalid_argument(
"event statistics capacity must be greater than zero");
for (auto& event : values_)
for (auto& statistic : event)
statistic = Sliding_Statistics{capacity};
}
void Event_Statistics_Accumulator::submit(
Event_Type type, std::uint64_t created_steady_ns,
std::uint64_t started_steady_ns,
std::uint64_t completed_steady_ns) {
const auto type_index = static_cast<std::size_t>(type);
if (type_index >= event_type_count || created_steady_ns == 0 ||
started_steady_ns < created_steady_ns ||
completed_steady_ns < started_steady_ns)
return;
const std::array samples{
static_cast<double>(started_steady_ns - created_steady_ns) / 1'000'000.0,
static_cast<double>(completed_steady_ns - started_steady_ns) / 1'000'000.0,
static_cast<double>(completed_steady_ns - created_steady_ns) / 1'000'000.0};
for (std::size_t index = 0; index < samples.size(); ++index)
state_.values[type_index][index] =
values_[type_index][index].submit(samples[index]);
}
const Event_Statistics_State& Event_Statistics_Accumulator::state() const noexcept {
return state_;
}
void Event_Statistics_Accumulator::reset() noexcept {
for (auto& event : values_)
for (auto& statistic : event)
statistic.reset();
state_ = {};
}
}
+35
View File
@@ -1,4 +1,6 @@
#pragma once
#include "frame_statistics.hpp"
#include <array>
#include <atomic>
#include <concepts>
#include <cstdint>
@@ -16,10 +18,39 @@ enum class Event_Type : std::uint8_t {
key_press,
key_release
};
inline constexpr std::size_t event_type_count =
static_cast<std::size_t>(Event_Type::key_release) + 1;
enum class Event_Statistic : std::uint8_t {
queue_wait_ms,
dispatch_ms,
total_ms,
count
};
inline constexpr std::size_t event_statistic_count =
static_cast<std::size_t>(Event_Statistic::count);
struct Event_Statistics_State {
std::array<std::array<Statistic_State, event_statistic_count>,
event_type_count> values{}; /* 按事件业务类型发布的定长延迟统计结果。 */
bool operator==(const Event_Statistics_State&) const = default;
};
class Event_Statistics_Accumulator final {
public:
explicit Event_Statistics_Accumulator(std::size_t capacity = 600);
void submit(Event_Type type, std::uint64_t created_steady_ns,
std::uint64_t started_steady_ns,
std::uint64_t completed_steady_ns);
[[nodiscard]] const Event_Statistics_State& state() const noexcept;
void reset() noexcept;
private:
std::array<std::array<Sliding_Statistics, event_statistic_count>,
event_type_count> values_; /* Scene 单帧准入域内增量维护的统计器。 */
Event_Statistics_State state_{}; /* 下一次 Scene State 交换时发布的结果。 */
};
/* 所有输入事件的公共业务基类。 */
struct Event {
struct Dispatch_Timing {
std::uint64_t frame_sequence{};
std::uint64_t created_steady_ns{};
std::uint64_t started_steady_ns{};
std::uint64_t completed_steady_ns{};
};
@@ -32,6 +63,10 @@ struct Event {
[[nodiscard]] Dispatch_Timing dispatch_timing() const noexcept;
Event_Type type; /* 事件种类;构造后保持不变。 */
private:
friend struct Scene;
void observe_with(Event_Statistics_Accumulator* accumulator) noexcept;
std::uint64_t created_steady_ns_{}; /* 事件对象进入 Scene 前的内核单调时刻。 */
Event_Statistics_Accumulator* statistics_{}; /* 所属 Scene 的统计器;不拥有且不得跨 Scene。 */
mutable bool accepted{}; /* 处理链是否已经消费事件。 */
mutable std::atomic_uint64_t dispatch_frame_sequence_{};
mutable std::atomic_uint64_t dispatch_started_steady_ns_{};
+14 -2
View File
@@ -7,7 +7,8 @@ inline std::uint64_t event_steady_time_ns() noexcept {
std::chrono::steady_clock::now().time_since_epoch()).count());
}
}
inline Event::Event(Event_Type value) : type(value) {}
inline Event::Event(Event_Type value)
: type(value), created_steady_ns_(detail::event_steady_time_ns()) {}
inline Event::~Event() = default;
inline void Event::accept() const noexcept { accepted = true; }
inline bool Event::is_accepted() const noexcept { return accepted; }
@@ -17,13 +18,24 @@ inline void Event::mark_dispatch_started(std::uint64_t frame_sequence) const noe
dispatch_started_steady_ns_.store(detail::event_steady_time_ns(), std::memory_order_release);
}
inline void Event::mark_dispatch_completed() const noexcept {
dispatch_completed_steady_ns_.store(detail::event_steady_time_ns(), std::memory_order_release);
const auto completed = detail::event_steady_time_ns();
dispatch_completed_steady_ns_.store(completed, std::memory_order_release);
if (statistics_)
statistics_->submit(
type, created_steady_ns_,
dispatch_started_steady_ns_.load(std::memory_order_acquire),
completed);
}
inline Event::Dispatch_Timing Event::dispatch_timing() const noexcept {
return {dispatch_frame_sequence_.load(std::memory_order_relaxed),
created_steady_ns_,
dispatch_started_steady_ns_.load(std::memory_order_acquire),
dispatch_completed_steady_ns_.load(std::memory_order_acquire)};
}
inline void Event::observe_with(
Event_Statistics_Accumulator* accumulator) noexcept {
statistics_ = accumulator;
}
constexpr Keyboard_Modifier operator|(Keyboard_Modifier left, Keyboard_Modifier right) noexcept { return static_cast<Keyboard_Modifier>(static_cast<std::uint8_t>(left) | static_cast<std::uint8_t>(right)); }
template <Event_Point Point> Basic_Pointer_Event<Point>::Basic_Pointer_Event(Event_Type value) : Event(value) {}
template <Event_Point Point> double Basic_Pointer_Event<Point>::position_x() const noexcept { return static_cast<double>(position.x); }
+1
View File
@@ -22,6 +22,7 @@ struct Scene : Def<Scene, Root,
struct Prop : Prev_Prop {};
/* Scene 每次 process(...) 后发布的总图结构与执行统计。 */
struct State : Prev_State {
Event_Statistics_State event_statistics{}; /* 输入进入 Scene 到 Renderable 消费完成的分类统计。 */
bool taskflow_rebuilt{}; /* 本次 process(...) 前的 advance 是否重新构建了总 Taskflow。 */
std::size_t renderable_count{}; /* Prepare 数据依赖图中的 Renderable 数量。 */
std::size_t taskflow_task_count{}; /* 当前 Prepare Taskflow 中的任务节点数量。 */
+8 -7
View File
@@ -10,10 +10,11 @@ struct Scene::Private : Prev_Private {
struct Result {}; /* process(...) 完成回调的结果类型;当前仅表示完成。 */
struct Runtime; /* Scene 的 Taskflow 构建产物;完整定义位于本文件下方。 */
std::unique_ptr<Runtime> runtime; /* Scene 唯一运行时构建产物的所有权。 */
Event_Statistics_Accumulator event_statistics{}; /* Scene 单帧域内按事件类型增量计算。 */
Private();
~Private();
template <Attached Object>
[[nodiscard]] Event_Batch take_events(Object* object, std::uint64_t frame_sequence);
[[nodiscard]] Event_Batch take_events(Object* object);
template <Attached Object> void bind_private_crtp(Object* object);
/* Def CRTP hook:所有缓冲推进后重建必要的总 Taskflow,并更新 Scene_State_Tag 状态层。 */
template <Attached Object>
@@ -39,23 +40,22 @@ void Scene::Private::bind_private_crtp(Object* object) {
runtime = std::make_unique<Runtime>();
}
template <Attached Object>
Scene::Event_Batch Scene::Private::take_events(Object* object, std::uint64_t frame_sequence) {
Scene::Event_Batch Scene::Private::take_events(Object* object) {
object->template exchange_stream<Scene_Event_Stream_Tag>();
return object->template access_rendering_stream<Scene_Event_Stream_Tag>(
[&](std::span<Event_Pointer> events) {
Event_Batch result{object->memory_resource()};
result.reserve(events.size());
for (const auto& event : events) {
event->mark_dispatch_started(frame_sequence);
result.push_back(event);
}
result.insert(result.end(), events.begin(), events.end());
return result;
});
}
template <Event_Object Event_Object_Type, typename... Arguments>
std::shared_ptr<Event_Object_Type> Scene::make_event(Arguments&&... arguments) {
return std::allocate_shared<Event_Object_Type>(
auto event = std::allocate_shared<Event_Object_Type>(
allocator<Event_Object_Type>(), std::forward<Arguments>(arguments)...);
event->observe_with(&static_cast<Private&>(*d).event_statistics);
return event;
}
template <Attached Object, typename Callback>
void Scene::Private::process(Object* object, Callback&& callback) requires std::invocable<Callback, const Result&> {
@@ -69,6 +69,7 @@ void Scene::Private::process(Object* object, Render_Frame* frame, Callback&& cal
if (frame) frame->mark(Frame_Trace_Marker::prepare_started);
if (runtime->taskflow && !runtime->taskflow->empty()) state.taskflow_execution_time_ns = detail::run_taskflow(*runtime->taskflow);
if (frame) frame->mark(Frame_Trace_Marker::prepare_finished);
state.event_statistics = event_statistics.state();
private_data.state.advance();
object->template notify_state<Scene::Base_Tag>();
Result result;