修复了一些bug

This commit is contained in:
2026-08-11 08:32:25 +08:00
parent feb7c72e94
commit b1fca95250
6 changed files with 394 additions and 150 deletions
+76 -21
View File
@@ -226,6 +226,8 @@ public:
std::uint64_t buffered_bytes,
std::uint64_t changed_pixel_frames,
std::uint64_t duplicate_pixel_frames,
std::uint64_t frame_request_timeout_count,
double last_pixel_receive_age_ms,
double last_pixel_change_age_ms) noexcept {
client_transport_fps_ = std::isfinite(transport_fps) ?
std::clamp(transport_fps, 0.0, 100000.0) : 0.0;
@@ -234,6 +236,9 @@ public:
client_buffered_bytes_ = buffered_bytes;
client_changed_pixel_frames_ = changed_pixel_frames;
client_duplicate_pixel_frames_ = duplicate_pixel_frames;
client_frame_request_timeout_count_ = frame_request_timeout_count;
client_last_pixel_receive_age_ms_ = std::isfinite(last_pixel_receive_age_ms) ?
std::max(0.0, last_pixel_receive_age_ms) : 0.0;
client_last_pixel_change_age_ms_ = std::isfinite(last_pixel_change_age_ms) ?
std::max(0.0, last_pixel_change_age_ms) : 0.0;
}
@@ -560,7 +565,9 @@ public:
std::chrono::duration<double>(telemetry_now - performance_started_).count(),
1e-9);
const double render_fps = recent_rate(render_history_, telemetry_now);
const double pixel_fps = recent_rate(pixel_history_, telemetry_now);
const double pixel_fps = recent_pixel_rate(pixel_history_, telemetry_now);
const double pixel_megabytes_per_second = recent_pixel_megabytes_per_second(
pixel_history_, telemetry_now);
nlohmann::json telemetry{
{"case", case_id_},
{"frame_mode", frame_mode_name(frame_mode_)},
@@ -587,8 +594,7 @@ public:
{"maximum_pixel_encode_ms", maximum_pixel_encode_ms_},
{"last_pixel_request_ms", last_pixel_request_ms_},
{"last_pixel_bytes", last_pixel_bytes_},
{"pixel_payload_megabytes_per_second",
pixel_fps * static_cast<double>(last_pixel_bytes_) / 1e6},
{"pixel_payload_megabytes_per_second", pixel_megabytes_per_second},
{"automatic_low_latency_scheduler",
automatic_low_latency_ && frame_mode_ == Gallery_Frame_Mode::Low_Latency},
{"kernel_paint_ms", static_cast<double>(observer.paint_duration_ns) / 1e6},
@@ -630,6 +636,8 @@ public:
{"websocket_buffered_bytes", client_buffered_bytes_},
{"changed_pixel_frames", client_changed_pixel_frames_},
{"duplicate_pixel_frames", client_duplicate_pixel_frames_},
{"frame_request_timeout_count", client_frame_request_timeout_count_},
{"last_pixel_receive_age_ms", client_last_pixel_receive_age_ms_},
{"last_pixel_change_age_ms", client_last_pixel_change_age_ms_}
}},
{"last_action_result", last_action_result_}
@@ -787,6 +795,10 @@ public:
private:
using Performance_Clock = std::chrono::steady_clock;
struct Pixel_Performance_Sample {
Performance_Clock::time_point time;
std::size_t bytes;
};
static void record_timestamp(std::deque<Performance_Clock::time_point>& history,
Performance_Clock::time_point now) {
@@ -805,6 +817,39 @@ private:
return seconds > 0.0 ? static_cast<double>(history.size() - 1) / seconds : 0.0;
}
static void record_pixel_sample(std::deque<Pixel_Performance_Sample>& history,
Performance_Clock::time_point now,
std::size_t bytes) {
history.push_back({now, bytes});
const auto oldest = now - std::chrono::seconds(1);
while (history.size() > 2 && history.front().time < oldest)
history.pop_front();
}
static double recent_pixel_rate(const std::deque<Pixel_Performance_Sample>& history,
Performance_Clock::time_point now) {
if (history.size() < 2 || now - history.back().time > std::chrono::seconds(1))
return 0.0;
const double seconds =
std::chrono::duration<double>(history.back().time - history.front().time).count();
return seconds > 0.0 ? static_cast<double>(history.size() - 1) / seconds : 0.0;
}
static double recent_pixel_megabytes_per_second(
const std::deque<Pixel_Performance_Sample>& history,
Performance_Clock::time_point now) {
if (history.size() < 2 || now - history.back().time > std::chrono::seconds(1))
return 0.0;
const double seconds =
std::chrono::duration<double>(history.back().time - history.front().time).count();
if (seconds <= 0.0)
return 0.0;
std::size_t bytes{};
for (std::size_t index = 1; index < history.size(); ++index)
bytes += history[index].bytes;
return static_cast<double>(bytes) / seconds / 1e6;
}
void record_performance(std::chrono::steady_clock::time_point started, bool rendered) {
const auto finished = std::chrono::steady_clock::now();
++render_attempt_count_;
@@ -834,7 +879,7 @@ private:
total_pixel_encode_ms_ += last_pixel_encode_ms_;
last_pixel_bytes_ = pixel_bytes;
++pixel_frame_count_;
record_timestamp(pixel_history_, encode_finished);
record_pixel_sample(pixel_history_, encode_finished, pixel_bytes);
}
void maybe_log_performance(Performance_Clock::time_point now) {
@@ -845,7 +890,9 @@ private:
const auto unix_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
const double pixel_fps = recent_rate(pixel_history_, now);
const double pixel_fps = recent_pixel_rate(pixel_history_, now);
const double pixel_megabytes_per_second = recent_pixel_megabytes_per_second(
pixel_history_, now);
const nlohmann::json line{
{"event", "gallery_performance"},
{"unix_ms", unix_ms},
@@ -860,14 +907,15 @@ private:
{"client_presentation_fps", client_presentation_fps_},
{"client_changed_pixel_frames", client_changed_pixel_frames_},
{"client_duplicate_pixel_frames", client_duplicate_pixel_frames_},
{"client_frame_request_timeout_count", client_frame_request_timeout_count_},
{"client_last_pixel_receive_age_ms", client_last_pixel_receive_age_ms_},
{"client_last_pixel_change_age_ms", client_last_pixel_change_age_ms_},
{"last_render_ms", last_render_ms_},
{"last_pixel_snapshot_ms", last_pixel_snapshot_ms_},
{"last_pixel_encode_ms", last_pixel_encode_ms_},
{"last_pixel_request_ms", last_pixel_request_ms_},
{"pixel_payload_bytes", last_pixel_bytes_},
{"pixel_payload_megabytes_per_second",
pixel_fps * static_cast<double>(last_pixel_bytes_) / 1e6},
{"pixel_payload_megabytes_per_second", pixel_megabytes_per_second},
{"websocket_buffered_bytes", client_buffered_bytes_},
{"automatic_low_latency_scheduler",
automatic_low_latency_ && frame_mode_ == Gallery_Frame_Mode::Low_Latency},
@@ -1371,12 +1419,14 @@ private:
double maximum_pixel_encode_ms_{};
double last_pixel_request_ms_{};
std::size_t last_pixel_bytes_{};
std::deque<Performance_Clock::time_point> pixel_history_;
std::deque<Pixel_Performance_Sample> pixel_history_;
double client_transport_fps_{};
double client_presentation_fps_{};
std::uint64_t client_buffered_bytes_{};
std::uint64_t client_changed_pixel_frames_{};
std::uint64_t client_duplicate_pixel_frames_{};
std::uint64_t client_frame_request_timeout_count_{};
double client_last_pixel_receive_age_ms_{};
double client_last_pixel_change_age_ms_{};
bool rendered_since_last_pixel_{};
std::string last_action_result_;
@@ -1385,12 +1435,7 @@ private:
struct Gallery_Plot_Session::Impl {
explicit Impl(bool enable_automatic_low_latency)
: automatic_low_latency(enable_automatic_low_latency),
session_id(next_session_id()) {
if (automatic_low_latency) {
render_worker = std::jthread(
[this](std::stop_token stop) { run_automatic_renderer(stop); });
}
}
session_id(next_session_id()) {}
~Impl() {
render_worker.request_stop();
@@ -1402,6 +1447,13 @@ struct Gallery_Plot_Session::Impl {
return next.fetch_add(1, std::memory_order_relaxed);
}
void ensure_render_worker() {
if (!automatic_low_latency || render_worker.joinable())
return;
render_worker = std::jthread(
[this](std::stop_token stop) { run_automatic_renderer(stop); });
}
void update_client_metrics(std::string_view message) {
if (!scene)
return;
@@ -1433,6 +1485,8 @@ struct Gallery_Plot_Session::Impl {
finite_metric("presentation_fps"), buffered_bytes,
unsigned_metric("changed_pixel_frames"),
unsigned_metric("duplicate_pixel_frames"),
unsigned_metric("frame_request_timeout_count"),
finite_metric("last_pixel_receive_age_ms"),
finite_metric("last_pixel_change_age_ms"));
}
@@ -1497,11 +1551,10 @@ struct Gallery_Plot_Session::Impl {
}
continue;
}
const auto spin_window = interval <= std::chrono::milliseconds(10) ?
std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::milliseconds(2)) :
std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::microseconds(250));
const auto spin_window = std::min(
interval / 4,
std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::microseconds(250)));
const auto coarse_deadline = deadline > cycle_started + spin_window ?
deadline - spin_window : cycle_started;
if (Clock::now() < coarse_deadline) {
@@ -1515,8 +1568,8 @@ struct Gallery_Plot_Session::Impl {
}
lock.unlock();
while (!stop.stop_requested() && Clock::now() < deadline) {
}
while (!stop.stop_requested() && Clock::now() < deadline)
std::this_thread::yield();
lock.lock();
}
}
@@ -1560,6 +1613,8 @@ struct Gallery_Plot_Session::Impl {
Gallery_Protocol::default_state(open->case_id, open->frame_mode),
open->frame_mode, automatic_low_latency);
++scene_generation;
if (scene->frame_mode() == Gallery_Frame_Mode::Low_Latency)
ensure_render_worker();
return Web_Response{Web_Response_Type::Json,
Gallery_Protocol::case_json(scene->case_id(), scene->state(),
scene->telemetry_json(),