自定义协议优化

This commit is contained in:
2026-08-11 16:34:24 +08:00
parent f2c1374a7f
commit de88da9a8a
8 changed files with 432 additions and 293 deletions
+202 -17
View File
@@ -48,6 +48,7 @@ struct Action_Model {
std::string argument_input;
std::string argument_label;
double argument_default{};
bool request_frame{};
};
struct Control_Definition {
@@ -403,6 +404,13 @@ Action_Definition action(std::string id, std::string label, std::string api,
argument_default}};
}
Action_Definition frame_action(std::string id, std::string label, std::string api,
std::string group) {
auto result = action(std::move(id), std::move(label), std::move(api), std::move(group));
result.model.request_frame = true;
return result;
}
std::vector<Action_Definition> actions(std::string_view case_id,
Gallery_Frame_Mode frame_mode) {
std::vector<Action_Definition> result{
@@ -418,30 +426,30 @@ std::vector<Action_Definition> actions(std::string_view case_id,
"Manual_Refresh_Strategy"));
result.push_back(action("mode_refresh", "提交手动刷新", "Manual_Refresh_Strategy::refresh / Plot_Core::refresh_manual_frame",
"Manual_Refresh_Strategy"));
result.push_back(action("mode_render", "渲染已刷新帧", "Manual_Refresh_Strategy::acquire_renderer / Plot_Core::render_prepared_frame",
"Manual_Refresh_Strategy"));
result.push_back(frame_action("mode_render", "渲染已刷新帧", "Manual_Refresh_Strategy::acquire_renderer / Plot_Core::render_prepared_frame",
"Manual_Refresh_Strategy"));
result.push_back(action("mode_discard", "丢弃待刷新帧", "Plot_Core::discard_pending_frame",
"Manual_Refresh_Strategy"));
result.push_back(action("mode_cycle", "执行完整手动帧周期", "Plot_Core::render_frame",
"Manual_Refresh_Strategy"));
result.push_back(frame_action("mode_cycle", "执行完整手动帧周期", "Plot_Core::render_frame",
"Manual_Refresh_Strategy"));
} else if (frame_mode == Gallery_Frame_Mode::Low_Latency) {
result.push_back(action("mode_prepare", "发布低延迟帧", "Low_Latency_Strategy::acquire_painter / Plot_Core::prepare_frame",
"Low_Latency_Strategy"));
result.push_back(action("mode_render", "消费最新帧", "Low_Latency_Strategy::acquire_renderer / Plot_Core::render_prepared_frame",
"Low_Latency_Strategy"));
result.push_back(frame_action("mode_render", "消费最新帧", "Low_Latency_Strategy::acquire_renderer / Plot_Core::render_prepared_frame",
"Low_Latency_Strategy"));
result.push_back(action("mode_discard", "丢弃陈旧帧", "Plot_Core::discard_pending_frame",
"Low_Latency_Strategy"));
result.push_back(action("mode_cycle", "执行低延迟帧周期", "Plot_Core::render_frame",
"Low_Latency_Strategy"));
result.push_back(frame_action("mode_cycle", "执行低延迟帧周期", "Plot_Core::render_frame",
"Low_Latency_Strategy"));
} else {
result.push_back(action("mode_enqueue", "压入一帧", "Flow_Refresh_Strategy::acquire_painter / Plot_Core::prepare_frame",
"Flow_Refresh_Strategy"));
result.push_back(action("mode_enqueue_burst", "批量压入回放队列", "Flow_Refresh_Strategy::acquire_painter / Plot_Core::prepare_frame × N",
"Flow_Refresh_Strategy", {}, "number", "帧数", 8));
result.push_back(action("mode_dequeue", "消费队首帧", "Flow_Refresh_Strategy::acquire_renderer / Plot_Core::render_prepared_frame",
"Flow_Refresh_Strategy"));
result.push_back(action("mode_cycle", "执行回放帧周期", "Plot_Core::render_frame",
"Flow_Refresh_Strategy"));
result.push_back(frame_action("mode_dequeue", "消费队首帧", "Flow_Refresh_Strategy::acquire_renderer / Plot_Core::render_prepared_frame",
"Flow_Refresh_Strategy"));
result.push_back(frame_action("mode_cycle", "执行回放帧周期", "Plot_Core::render_frame",
"Flow_Refresh_Strategy"));
}
if (case_id == "axis_lab") {
result.push_back(action("append_time", "追加时间点", "Time_Axis::append_time / tick_to_time", "Time_Axis"));
@@ -651,7 +659,8 @@ struct Type_Descriptor<renderive::web::gallery_detail::Action_Model> {
ADMINIVE_FIELD_LABEL(T, group, "分组"),
ADMINIVE_FIELD_LABEL(T, argument_input, "参数类型"),
ADMINIVE_FIELD_LABEL(T, argument_label, "参数名称"),
ADMINIVE_FIELD_LABEL(T, argument_default, "参数默认值"))
ADMINIVE_FIELD_LABEL(T, argument_default, "参数默认值"),
ADMINIVE_FIELD_LABEL(T, request_frame, "执行后请求像素帧"))
.label("后端动作菜单");
}
};
@@ -689,7 +698,7 @@ using gallery_detail::Json;
Json protocol_base() {
return {{"category", "gallery"},
{"protocol", "renderive.control-gallery"},
{"protocol_version", 3}};
{"protocol_version", 4}};
}
Json case_contract(std::string_view case_id) {
@@ -719,23 +728,192 @@ std::optional<Gallery_Frame_Mode> parse_frame_mode(std::string_view value) {
return std::nullopt;
}
Json dashboard_field(std::string_view label, std::string_view source,
std::string_view format = "integer", int digits = -1) {
Json result{{"label", label}, {"source", source}, {"format", format}};
if (digits >= 0)
result["digits"] = digits;
return result;
}
Json mapped_dashboard_field(std::string_view label, std::string_view source,
std::string_view format, std::string_view value_map) {
Json result = dashboard_field(label, source, format);
result["value_map"] = value_map;
return result;
}
Json dashboard_contract() {
Json point_pair{{"label", "输入→绘制"}, {"format", "pair"},
{"sources", Json::array({"data_shape.input_points", "data_shape.rendered_elements"})},
{"separator", ""}};
Json bottleneck = mapped_dashboard_field("当前瓶颈", "low_latency_limit.current",
"duration_enum", "limit_state");
bottleneck["duration_sources"] = {
{"frequency_limited", "kernel_observer.target_interval_ns"},
{"paint_limited", "kernel_observer.paint_duration_ns"},
{"render_limited", "kernel_observer.render_duration_ns"},
{"consumer_limited", "kernel_observer.consumer_interval_ns"}
};
Json configured_frequency = dashboard_field("配置频率", "kernel_observer.configured_frequency_hz",
"frequency");
configured_frequency["enabled_source"] = "kernel_observer.frequency_limit_enabled";
configured_frequency["disabled_label"] = "已关闭";
Json dashboard{
{"value_maps", {
{"enabled", {{"true", "启用"}, {"false", "关闭"}}},
{"consumer_feedback_source", {
{"disabled", "总开关关闭"}, {"none", ""}, {"pixel", "像素响应"},
{"presentation", "浏览器呈现"}, {"manual", "手动"}
}},
{"limit_state", {
{"frequency_limited", "Kernel 频率受限"}, {"paint_limited", "PaintEvent 受限"},
{"render_limited", "后台渲染受限"}, {"consumer_limited", "消费者反馈受限"},
{"unlimited", "无限制"}, {"not_applicable", "N/A"}
}}
}},
{"performance", {
{"fields", Json::array({
dashboard_field("后端渲染 FPS", "performance.measured_fps", "fixed", 1),
dashboard_field("像素响应 FPS", "performance.pixel_response_fps", "fixed", 1),
dashboard_field("浏览器呈现 FPS", "client_performance.presentation_fps", "fixed", 1),
dashboard_field("WS 往返 ms", "client_performance.frame_round_trip_ms", "fixed", 2),
dashboard_field("未呈现覆盖", "client_performance.overwritten_pixel_frames"),
dashboard_field("Core 渲染 ms", "performance.last_render_ms", "fixed", 2),
dashboard_field("像素编码 ms", "performance.last_pixel_encode_ms", "fixed", 2),
dashboard_field("响应负载 MB/s", "performance.pixel_payload_megabytes_per_second", "fixed", 1),
dashboard_field("Kernel 待处理", "kernel_observer.pending_frame_count"),
dashboard_field("Kernel 丢弃", "kernel_observer.dropped_frame_count"),
std::move(point_pair), std::move(bottleneck),
dashboard_field("观察事件", "kernel_observer.last_event", "text"),
dashboard_field("像素超时", "client_performance.frame_request_timeout_count"),
dashboard_field("最近像素龄", "client_performance.last_pixel_receive_age_ms", "milliseconds", 0)
})}
}},
{"menu_views", {
{"observer", {{"source", "kernel_observer"}}},
{"performance", Json::object()}
}},
{"limits", {
{"aria_label", "低延迟限速来源"}, {"title", "限速来源"},
{"current_source", "low_latency_limit.current"},
{"active_label", "当前瓶颈"}, {"inactive_label", "未受限"},
{"disabled_label", "已关闭"},
{"fields", Json::array({
{{"label", "Kernel 用户频率"}, {"active_value", "frequency_limited"},
{"duration_source", "kernel_observer.target_interval_ns"},
{"enabled_source", "kernel_observer.frequency_limit_enabled"}},
{{"label", "Kernel PaintEvent"}, {"active_value", "paint_limited"},
{"duration_source", "kernel_observer.paint_duration_ns"}},
{{"label", "Kernel 后台渲染"}, {"active_value", "render_limited"},
{"duration_source", "kernel_observer.render_duration_ns"}},
{{"label", "消费者反馈"}, {"active_value", "consumer_limited"},
{"duration_source", "kernel_observer.consumer_interval_ns"},
{"enabled_source", "kernel_observer.consumer_feedback_enabled"}}
})}
}},
{"observer", {
{"aria_label", "Kernel 低延迟全量统计"},
{"header", {
{"prefix", "KERNEL"}, {"suffix", "OBSERVER"}, {"event_label", "事件"},
{"mode", dashboard_field("", "kernel_observer.mode", "text")},
{"limit", mapped_dashboard_field("", "kernel_observer.limit_state", "enum", "limit_state")},
{"event", dashboard_field("", "kernel_observer.last_event", "text")}
}},
{"sections", Json::array({
{{"class_name", "observer-counters"}, {"fields", Json::array({
std::move(configured_frequency),
dashboard_field("观察次数", "kernel_observer.observation_count"),
dashboard_field("最新序号", "kernel_observer.latest_sequence"),
dashboard_field("发布", "kernel_observer.produced_frame_count"),
dashboard_field("完成", "kernel_observer.consumed_frame_count"),
dashboard_field("待处理", "kernel_observer.pending_frame_count"),
dashboard_field("丢弃", "kernel_observer.dropped_frame_count"),
dashboard_field("失败", "kernel_observer.failed_operation_count")
})}},
{{"class_name", "latency-summary"}, {"fields", Json::array({
dashboard_field("目标间隔", "kernel_observer.target_interval_ns", "nanoseconds"),
dashboard_field("PaintEvent", "kernel_observer.paint_duration_ns", "nanoseconds"),
dashboard_field("后台渲染", "kernel_observer.render_duration_ns", "nanoseconds"),
dashboard_field("内部瓶颈", "kernel_observer.bottleneck_duration_ns", "nanoseconds"),
mapped_dashboard_field("消费者总开关", "kernel_observer.consumer_feedback_master_enabled", "enum", "enabled"),
mapped_dashboard_field("Kernel 反馈有效", "kernel_observer.consumer_feedback_enabled", "enum", "enabled"),
mapped_dashboard_field("像素响应反馈", "kernel_observer.consumer_pixel_feedback_enabled", "enum", "enabled"),
mapped_dashboard_field("浏览器呈现反馈", "kernel_observer.consumer_presentation_feedback_enabled", "enum", "enabled"),
mapped_dashboard_field("手动消费者反馈", "kernel_observer.consumer_manual_feedback_enabled", "enum", "enabled"),
dashboard_field("手动消费者 FPS", "kernel_observer.consumer_manual_fps", "fps", 2),
mapped_dashboard_field("生效反馈来源", "kernel_observer.consumer_feedback_source", "flags", "consumer_feedback_source"),
dashboard_field("像素响应周期", "kernel_observer.consumer_pixel_interval_ns", "nanoseconds"),
dashboard_field("浏览器呈现周期", "kernel_observer.consumer_presentation_interval_ns", "nanoseconds"),
dashboard_field("手动消费者周期", "kernel_observer.consumer_manual_interval_ns", "nanoseconds"),
dashboard_field("消费者原始采样", "kernel_observer.consumer_sample_interval_ns", "nanoseconds"),
dashboard_field("消费者平滑周期", "kernel_observer.consumer_smoothed_interval_ns", "nanoseconds"),
dashboard_field("消费者抖动", "kernel_observer.consumer_variation_ns", "nanoseconds"),
dashboard_field("消费者安全期限", "kernel_observer.consumer_safety_interval_ns", "nanoseconds"),
dashboard_field("消费者限速周期", "kernel_observer.consumer_interval_ns", "nanoseconds"),
dashboard_field("消费者限速 FPS", "kernel_observer.consumer_interval_ns", "inverse_fps", 2),
dashboard_field("下次刷新", "kernel_observer.next_refresh_interval_ns", "nanoseconds"),
Json{{"label", "端到端延迟"}, {"source", "kernel_observer.end_to_end_ns"},
{"format", "nanoseconds"}, {"cell_class", "critical"}}
})}},
{{"class_name", "client-summary"}, {"aria_label", "浏览器消费者反馈全量统计"},
{"fields", Json::array({
dashboard_field("RAF 最新周期", "client_performance.display_interval_latest_ms", "milliseconds", 3),
dashboard_field("RAF 中位周期", "client_performance.display_interval_ms", "milliseconds", 3),
dashboard_field("RAF P95 周期", "client_performance.display_interval_p95_ms", "milliseconds", 3),
dashboard_field("RAF P95-P50 抖动", "client_performance.display_jitter_ms", "milliseconds", 3),
dashboard_field("WS 往返", "client_performance.frame_round_trip_ms", "milliseconds", 3),
dashboard_field("像素响应 FPS", "client_performance.transport_fps", "fps", 2),
dashboard_field("浏览器呈现 FPS", "client_performance.presentation_fps", "fps", 2),
dashboard_field("WS 缓冲", "client_performance.websocket_buffered_bytes", "bytes"),
dashboard_field("未呈现覆盖", "client_performance.overwritten_pixel_frames"),
dashboard_field("变化像素帧", "client_performance.changed_pixel_frames"),
dashboard_field("重复像素帧", "client_performance.duplicate_pixel_frames"),
dashboard_field("像素请求超时", "client_performance.frame_request_timeout_count"),
dashboard_field("最近像素龄", "client_performance.last_pixel_receive_age_ms", "milliseconds", 3),
dashboard_field("最近变化龄", "client_performance.last_pixel_change_age_ms", "milliseconds", 3)
})}},
{{"class_name", "latency-details"}, {"aria_label", "Kernel 各阶段等待耗时"},
{"fields", Json::array({
dashboard_field("Painter Lease 等待", "kernel_observer.paint_lease_wait_ns", "nanoseconds"),
dashboard_field("Paint State 等待", "kernel_observer.paint_state_wait_ns", "nanoseconds"),
dashboard_field("Publish State 等待", "kernel_observer.publish_state_wait_ns", "nanoseconds"),
dashboard_field("Ready 等待", "kernel_observer.ready_wait_ns", "nanoseconds"),
dashboard_field("开始渲染时帧龄", "kernel_observer.frame_age_at_render_ns", "nanoseconds"),
dashboard_field("Render Lease 等待", "kernel_observer.render_lease_wait_ns", "nanoseconds"),
dashboard_field("Render State 等待", "kernel_observer.render_state_wait_ns", "nanoseconds"),
dashboard_field("Render Finish 等待", "kernel_observer.render_finish_state_wait_ns", "nanoseconds"),
dashboard_field("回放队列等待", "kernel_observer.queue_wait_ns", "nanoseconds")
})}}
})}
}}
};
return dashboard;
}
Json frame_mode_contract(Gallery_Frame_Mode mode) {
switch (mode) {
case Gallery_Frame_Mode::Manual:
return {{"id", "manual"}, {"title", "手动刷新"},
{"strategy", "Manual_Refresh_Strategy"},
{"description", "显式准备、刷新和渲染;页面不会自动拉取像素。"},
{"automatic", false}, {"order", 10}};
{"automatic", false}, {"request_after_response", false},
{"request_on_animation_frame", false}, {"observer_visible", false},
{"frame_button_label", "手动刷新一帧"}, {"accent", "#ffd166aa"}, {"order", 10}};
case Gallery_Frame_Mode::Low_Latency:
return {{"id", "low_latency"}, {"title", "低延迟"},
{"strategy", "Low_Latency_Strategy"},
{"description", "以最大 FPS 自动发布并消费最新帧,可观测丢帧与端到端延迟。"},
{"automatic", true}, {"order", 20}};
{"automatic", true}, {"request_after_response", true},
{"request_on_animation_frame", false}, {"observer_visible", true},
{"frame_button_label", "立即刷新"}, {"accent", "#45ddbeaa"}, {"order", 20}};
case Gallery_Frame_Mode::Playback:
return {{"id", "playback"}, {"title", "回放队列"},
{"strategy", "Flow_Refresh_Strategy"},
{"description", "所有帧按队列顺序入队和消费,可观测队深与排队时间。"},
{"automatic", true}, {"order", 30}};
{"automatic", true}, {"request_after_response", true},
{"request_on_animation_frame", true}, {"observer_visible", false},
{"frame_button_label", "消费下一帧"}, {"accent", "#6aa9ffaa"}, {"order", 30}};
}
return Json::object();
}
@@ -747,6 +925,13 @@ std::string Gallery_Protocol::catalog_json() {
result["type"] = "catalog";
result["transport"] = {{"events", "websocket-text"}, {"pixels", "websocket-binary-rvp1"},
{"http_api", false}, {"socket_per_canvas", true}};
result["navigation"] = {
{"default_mode", "low_latency"}, {"all_categories_label", "全部"},
{"catalog_loaded_text", "Kernel 策略目录已加载"},
{"hero_eyebrow", "REAL KERNEL STRATEGIES"},
{"hero_title", "对称策略页面,同一批控件,直接比较"}
};
result["dashboard"] = dashboard_contract();
result["case_descriptor"] =
adminive::to_descriptor_json<Json, gallery_detail::Case_Model>();
result["frame_modes"] = Json::array();