3D性能优化
This commit is contained in:
+31
-21
@@ -33,7 +33,7 @@ using Frequency_Axis_Object = Impl<Frequency_Axis>;
|
||||
using Numeric_Axis_Object = Impl<Numeric_Axis>;
|
||||
using Time_Axis_Object = Impl<Time_Axis>;
|
||||
using Selection_Object = Impl<Selection_Rectangle_Overlay>;
|
||||
constexpr std::uint16_t frame_protocol_version{4};
|
||||
constexpr std::uint16_t frame_protocol_version{5};
|
||||
enum class Frame_Pacing_Mode : std::uint32_t {
|
||||
manual,
|
||||
fixed_rate,
|
||||
@@ -70,6 +70,13 @@ std::optional<Frame_Pacing_Mode> parse_pacing_mode(std::string_view value) {
|
||||
if (value == "maximum_rate") return Frame_Pacing_Mode::maximum_rate;
|
||||
return std::nullopt;
|
||||
}
|
||||
std::string_view delivery_name(Plot_Frame_Delivery delivery) {
|
||||
switch (delivery) {
|
||||
case Plot_Frame_Delivery::pixels: return "pixels";
|
||||
case Plot_Frame_Delivery::diagnostics: return "diagnostics";
|
||||
}
|
||||
throw std::logic_error("unknown plot frame delivery");
|
||||
}
|
||||
Frame_Pacing_Properties Frame_Policy::snapshot() const {
|
||||
std::lock_guard lock(mutex);
|
||||
return pacing;
|
||||
@@ -107,7 +114,7 @@ nlohmann::json Frame_Policy::write_prop(std::string_view key, const nlohmann::js
|
||||
}
|
||||
return {{"success", false}, {"error", "unknown frame runtime property"}};
|
||||
}
|
||||
nlohmann::json frame_metadata(Render_Frame& frame, std::uint32_t width, std::uint32_t height, std::size_t byte_length, const Frame_Pacing_Properties& pacing) {
|
||||
nlohmann::json frame_metadata(Render_Frame& frame, std::uint32_t width, std::uint32_t height, std::size_t byte_length, Plot_Frame_Delivery delivery, const Frame_Pacing_Properties& pacing) {
|
||||
nlohmann::json markers = nlohmann::json::object();
|
||||
for (const auto& point : frame.trace_points()) markers[std::string(magic_enum::enum_name(point.marker))] = point.elapsed_ns;
|
||||
nlohmann::json measurements = nlohmann::json::object();
|
||||
@@ -116,42 +123,44 @@ nlohmann::json frame_metadata(Render_Frame& frame, std::uint32_t width, std::uin
|
||||
return {
|
||||
{"kind", "frame_metadata"}, {"protocol", "aethera.frame"}, {"version", frame_protocol_version},
|
||||
{"sequence", identity.sequence}, {"correlation_id", identity.correlation_id},
|
||||
{"created_time_unix_ms", static_cast<double>(frame.created_time_unix_ns()) / 1'000'000.0},
|
||||
{"created_time_unix_ms", static_cast<double>(frame.created_time_unix_ns()) / 1'000'000.0}, {"delivery", delivery_name(delivery)},
|
||||
{"pixel", {{"width", width}, {"height", height}, {"format", "rgba8"}, {"byte_length", byte_length}}},
|
||||
{"pacing", {{"mode", pacing_mode_name(pacing.mode)}, {"fixed_rate_fps", pacing.fixed_rate_fps}, {"minimum_latency_headroom", pacing.minimum_latency_headroom}}},
|
||||
{"trace", {{"clock", "steady_elapsed_ns"}, {"markers", std::move(markers)}, {"measurements", std::move(measurements)}}}
|
||||
};
|
||||
}
|
||||
std::shared_ptr<const Plot_Frame_Message> encode_frame(Frame_2D* frame, const Frame_Pacing_Properties& pacing) {
|
||||
std::shared_ptr<const Plot_Frame_Message> encode_frame(Frame_2D* frame, Plot_Frame_Delivery delivery, const Frame_Pacing_Properties& pacing) {
|
||||
frame->mark(Frame_Trace_Marker::websocket_publish_started);
|
||||
const Image_View image = frame->image();
|
||||
std::string output;
|
||||
output.reserve(static_cast<std::size_t>(image.width) * image.height * 4);
|
||||
for (int y = 0; y < image.height; ++y) {
|
||||
const auto* row = reinterpret_cast<const std::uint8_t*>(
|
||||
image.data + static_cast<std::ptrdiff_t>(y) * image.stride);
|
||||
for (int x = 0; x < image.width; ++x) {
|
||||
const auto* pixel = row + x * 4;
|
||||
output.push_back(static_cast<char>(pixel[2]));
|
||||
output.push_back(static_cast<char>(pixel[1]));
|
||||
output.push_back(static_cast<char>(pixel[0]));
|
||||
output.push_back(static_cast<char>(pixel[3]));
|
||||
if (delivery == Plot_Frame_Delivery::pixels) {
|
||||
output.reserve(static_cast<std::size_t>(image.width) * image.height * 4);
|
||||
for (int y = 0; y < image.height; ++y) {
|
||||
const auto* row = reinterpret_cast<const std::uint8_t*>(
|
||||
image.data + static_cast<std::ptrdiff_t>(y) * image.stride);
|
||||
for (int x = 0; x < image.width; ++x) {
|
||||
const auto* pixel = row + x * 4;
|
||||
output.push_back(static_cast<char>(pixel[2]));
|
||||
output.push_back(static_cast<char>(pixel[1]));
|
||||
output.push_back(static_cast<char>(pixel[0]));
|
||||
output.push_back(static_cast<char>(pixel[3]));
|
||||
}
|
||||
}
|
||||
}
|
||||
frame->mark(Frame_Trace_Marker::websocket_publish_finished);
|
||||
auto message = std::make_shared<Plot_Frame_Message>();
|
||||
message->pixels = std::move(output);
|
||||
message->metadata = frame_metadata(*frame, static_cast<std::uint32_t>(image.width), static_cast<std::uint32_t>(image.height), message->pixels.size(), pacing).dump();
|
||||
message->metadata = frame_metadata(*frame, static_cast<std::uint32_t>(image.width), static_cast<std::uint32_t>(image.height), message->pixels.size(), delivery, pacing).dump();
|
||||
return message;
|
||||
}
|
||||
std::shared_ptr<const Plot_Frame_Message> encode_frame(Frame_3D* frame, const Frame_Pacing_Properties& pacing) {
|
||||
std::shared_ptr<const Plot_Frame_Message> encode_frame(Frame_3D* frame, Plot_Frame_Delivery delivery, const Frame_Pacing_Properties& pacing) {
|
||||
frame->mark(Frame_Trace_Marker::websocket_publish_started);
|
||||
const auto pixels = frame->pixels();
|
||||
auto message = std::make_shared<Plot_Frame_Message>();
|
||||
message->pixels.assign(reinterpret_cast<const char*>(pixels.data()), pixels.size());
|
||||
if (delivery == Plot_Frame_Delivery::pixels) message->pixels.assign(reinterpret_cast<const char*>(pixels.data()), pixels.size());
|
||||
frame->mark(Frame_Trace_Marker::websocket_publish_finished);
|
||||
const auto extent = frame->extent();
|
||||
message->metadata = frame_metadata(*frame, extent.width, extent.height, message->pixels.size(), pacing).dump();
|
||||
message->metadata = frame_metadata(*frame, extent.width, extent.height, message->pixels.size(), delivery, pacing).dump();
|
||||
return message;
|
||||
}
|
||||
struct Schema_Query {
|
||||
@@ -273,7 +282,8 @@ nlohmann::json Plot::Private::schema() const {
|
||||
Plot::Private::Managed_Frame Plot::Private::make_frame(Frame_Submission submission) {
|
||||
const Frame_Identity identity{next_frame_sequence++, submission.request.correlation_id};
|
||||
if (std::holds_alternative<std::unique_ptr<Scene_2D>>(scene)) return {submission.owner, std::move(submission.request), std::make_unique<Frame_2D>(identity)};
|
||||
return {submission.owner, std::move(submission.request), std::make_unique<Frame_3D>(identity)};
|
||||
const auto output = submission.request.delivery == Plot_Frame_Delivery::pixels ? Frame_3D_Output::pixels : Frame_3D_Output::diagnostics;
|
||||
return {submission.owner, std::move(submission.request), std::make_unique<Frame_3D>(identity, output)};
|
||||
}
|
||||
void Plot::Private::request_frame(Frame_Submission submission) {
|
||||
auto frame = make_frame(std::move(submission));
|
||||
@@ -316,8 +326,8 @@ void Plot::Private::render_frame(Managed_Frame frame) {
|
||||
void Plot::Private::publish_completed_frame(Render_Frame* frame) {
|
||||
if (!active_frame) throw std::logic_error("frame callback has no externally owned active frame");
|
||||
const auto pacing = frame_policy.snapshot();
|
||||
if (auto* frame_2d = std::get_if<std::unique_ptr<Frame_2D>>(&active_frame->frame); frame_2d && frame_2d->get() == frame) publish(active_frame->owner, encode_frame(frame_2d->get(), pacing));
|
||||
else if (auto* frame_3d = std::get_if<std::unique_ptr<Frame_3D>>(&active_frame->frame); frame_3d && frame_3d->get() == frame) publish(active_frame->owner, encode_frame(frame_3d->get(), pacing));
|
||||
if (auto* frame_2d = std::get_if<std::unique_ptr<Frame_2D>>(&active_frame->frame); frame_2d && frame_2d->get() == frame) publish(active_frame->owner, encode_frame(frame_2d->get(), active_frame->request.delivery, pacing));
|
||||
else if (auto* frame_3d = std::get_if<std::unique_ptr<Frame_3D>>(&active_frame->frame); frame_3d && frame_3d->get() == frame) publish(active_frame->owner, encode_frame(frame_3d->get(), active_frame->request.delivery, pacing));
|
||||
else throw std::logic_error("frame callback does not match the externally owned active frame");
|
||||
frame_completed();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user