3D优化完成

This commit is contained in:
2026-08-28 21:11:39 +08:00
parent 93d3f93774
commit 647ad6a66c
36 changed files with 1974 additions and 1548 deletions
+34 -7
View File
@@ -302,8 +302,8 @@ nlohmann::json datoviz_observation_json(
{"prepare_released_after_submission",
value.prepare_released_after_submission},
{"timings_ms", {
{"render_domain_queue_wait",
milliseconds(value.render_domain_queue_wait_ns)},
{"queue_submit_wait",
milliseconds(value.queue_submit_wait_ns)},
{"apply", milliseconds(value.apply_ns)},
{"emit", milliseconds(value.emit_ns)},
{"execute", milliseconds(value.execute_ns)},
@@ -535,6 +535,7 @@ struct Plot::Private {
std::unique_ptr<Scene_View> view;
std::once_flag start_once;
std::weak_ptr<Plot> lifetime{}; /* 仅用于 completion 后重新投递 Taskflow,避免在 Scene callback 内重入 render。 */
std::atomic<std::shared_ptr<Plot>> frame_policy_lifetime{}; /* 任一物理帧被借用期间由策略保活整个 Plot;最后一槽归还后释放。 */
std::atomic<std::shared_ptr<const Consumer_Map>> consumers{
std::make_shared<const Consumer_Map>()}; /* 低频订阅修改发布不可变版本。 */
std::atomic_uint64_t next_stream_id{1};
@@ -550,7 +551,7 @@ struct Plot::Private {
Scene scene; /* 析构顺序保证 Scene 先停止,再释放物理帧。 */
moodycamel::ConcurrentQueue<Plot_Render_Tick> tick_requests{}; /* 多生产者提交、唯一短任务消费的帧请求流。 */
std::optional<Plot_Render_Tick> deferred_tick{}; /* 仅 tick consumer 任务访问的 latest 延后请求。 */
std::atomic_uint64_t tick_request_generation{}; /* 请求入队后推进,用于关闭 consumer 尾部唤醒竞争窗口。 */
std::atomic_uint64_t consumer_work_generation{}; /* tick 或退休帧入队后推进,关闭 consumer 尾部唤醒竞争窗口。 */
std::atomic_bool tick_task_scheduled{}; /* 唯一短任务准入;不占用 Worker 等待。 */
std::atomic<Render_Admission_State> render_admission{Render_Admission_State::ready}; /* Plot 渲染准入及物理槽背压的唯一状态源。 */
std::chrono::steady_clock::time_point clock_origin{std::chrono::steady_clock::now()};
@@ -633,6 +634,8 @@ struct Plot::Private {
void keep_latest_tick(const Plot_Render_Tick& tick);
void arm_tick_consumer(std::weak_ptr<Plot> lifetime);
void release_render_admission(std::weak_ptr<Plot> lifetime);
void retain_frame_policy_lifetime();
void release_frame_policy_lifetime_if_idle();
void consume_tick(std::weak_ptr<Plot> lifetime);
void refresh_schedule();
void clock_tick(const Plot_Render_Tick& tick);
@@ -772,7 +775,7 @@ void Plot::Private::submit_tick_request(Plot_Render_Tick tick) {
with_frame_policy([&](auto& policy) {
policy.record_request(source, issued_at);
});
tick_request_generation.fetch_add(1, std::memory_order_release);
consumer_work_generation.fetch_add(1, std::memory_order_release);
}
void Plot::Private::keep_latest_tick(const Plot_Render_Tick& tick) {
@@ -831,11 +834,31 @@ void Plot::Private::release_render_admission(std::weak_ptr<Plot> lifetime) {
arm_tick_consumer(std::move(lifetime));
}
void Plot::Private::retain_frame_policy_lifetime() {
if (frame_policy_lifetime.load(std::memory_order_acquire)) return;
const auto owner = lifetime.lock();
if (!owner)
throw std::logic_error(
"Plot frame policy cannot retain an expired Plot");
std::shared_ptr<Plot> empty;
static_cast<void>(frame_policy_lifetime.compare_exchange_strong(
empty, owner, std::memory_order_release, std::memory_order_acquire));
}
void Plot::Private::release_frame_policy_lifetime_if_idle() {
if (std::ranges::any_of(frame_slots, [](const Managed_Frame& slot) {
return slot.state.load(std::memory_order_acquire) !=
Frame_State::available;
}))
return;
frame_policy_lifetime.store({}, std::memory_order_release);
}
void Plot::Private::consume_tick(std::weak_ptr<Plot> lifetime) {
const auto observed_generation =
consumer_work_generation.load(std::memory_order_acquire);
consume_retired_frames();
if (consume_frame_policy_events()) refresh_schedule();
const auto observed_generation =
tick_request_generation.load(std::memory_order_acquire);
Plot_Render_Tick requested;
while (tick_requests.try_dequeue(requested))
keep_latest_tick(requested);
@@ -847,7 +870,7 @@ void Plot::Private::consume_tick(std::weak_ptr<Plot> lifetime) {
consume_retired_frames();
if (consume_frame_policy_events()) refresh_schedule();
tick_task_scheduled.store(false, std::memory_order_release);
if (tick_request_generation.load(std::memory_order_acquire) !=
if (consumer_work_generation.load(std::memory_order_acquire) !=
observed_generation ||
retired_frames.load(std::memory_order_acquire) ||
(render_admission.load(std::memory_order_acquire) ==
@@ -1019,6 +1042,7 @@ void Plot::Private::render_frame(Plot_Render_Tick tick) {
std::memory_order_release);
return;
}
retain_frame_policy_lifetime();
managed->presentation_time =
std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::duration<double, std::milli>(tick.time_milliseconds));
@@ -1030,6 +1054,7 @@ void Plot::Private::render_frame(Plot_Render_Tick tick) {
static_cast<void>(slot.state.compare_exchange_strong(
expected, Frame_State::available, std::memory_order_acq_rel,
std::memory_order_acquire));
release_frame_policy_lifetime_if_idle();
};
bool taskflow_trace_claimed{};
const auto restore_taskflow_trace_claim = [this, &taskflow_trace_claimed] {
@@ -1356,6 +1381,7 @@ void Plot::Private::retire_completed_frame(not_null<Render_Frame*> frame) {
} while (!retired_frames.compare_exchange_weak(
head, managed, std::memory_order_release,
std::memory_order_relaxed));
consumer_work_generation.fetch_add(1, std::memory_order_release);
arm_tick_consumer(lifetime);
}
@@ -1442,6 +1468,7 @@ void Plot::Private::finalize_retired_frame(not_null<Render_Frame*> frame) {
admission, Render_Admission_State::ready,
std::memory_order_acq_rel, std::memory_order_acquire));
arm_tick_consumer(lifetime);
release_frame_policy_lifetime_if_idle();
if (captured_trace) {
auto owner = lifetime;