名称优化

This commit is contained in:
2026-08-02 03:43:39 +08:00
parent d8e023cea7
commit 3d027967b9
109 changed files with 1699 additions and 3979 deletions
+31 -99
View File
@@ -8,11 +8,8 @@
#include <algorithm>
#include <memory>
#include <utility>
namespace renderive {
class Plot_Core_Private;
struct Frame_Render_Job {
std::shared_ptr<Plot_Core_Private> owner;
std::uint64_t generation{};
@@ -21,53 +18,44 @@ struct Frame_Render_Job {
std::shared_ptr<Frame_Lifecycle_Record> lifecycle;
Plot_Render_Snapshot render_snapshot;
Renderable_Tree_Snapshot renderables;
std::shared_ptr<Frame_Worker_Stat> worker_stat;
std::shared_ptr<Frame_Worker_Stats> worker_stat;
};
class Plot_Core_Private final : public std::enable_shared_from_this<Plot_Core_Private> {
public:
explicit Plot_Core_Private(std::unique_ptr<Refresh_Strategy> s)
: strategy(std::move(s)) {}
~Plot_Core_Private() = default;
bool render_enabled() const {
return rendering.load(std::memory_order_acquire);
}
bool destroying() const {
return destroying_flag.load(std::memory_order_acquire);
}
Refresh_Runtime_Snapshot refresh_runtime_snapshot(std::uint64_t now_ns = steady_now_ns()) const {
return {
render_enabled(),
destroying(),
pipeline.has_new_state(),
pipeline.job_state != Plot_Render_Job_State::Idle,
pipeline.middle_has_new_frame(),
pipeline.paint_active(),
pipeline.has_unrendered_edit(),
pipeline.render_job_state != Frame_Job_State::Idle,
pipeline.middle_frame_ready(),
pipeline.painting_frame_in_use(),
now_ns
};
}
bool submit_render_once() {
if (!rendering.load(std::memory_order_acquire) || destroying_flag.load(std::memory_order_acquire))
return false;
if (!root)
return false;
Size size{
context->render_width.load(std::memory_order_acquire),
context->render_height.load(std::memory_order_acquire)
};
if (size.empty())
return false;
auto frame_lease = pipeline.try_begin_render();
auto frame_lease = pipeline.try_acquire_render_frame();
if (!frame_lease)
return false;
Plot_Frame* buffer = frame_lease.frame;
cancel_update_states(buffer->presented_update_states);
std::uint64_t render_role_enter_ns = buffer->metadata ? buffer->metadata->render_role_enter_ns : 0;
@@ -76,7 +64,7 @@ public:
Frame_Lifecycle_Record& frame = *frame_record;
std::uint64_t submit_time = steady_now_ns();
frame.frame_id = ++next_frame_id;
frame.input_version = pipeline.edit_state_version.load(std::memory_order_acquire);
frame.input_version = pipeline.edit_version.load(std::memory_order_acquire);
frame.render_request_ns = submit_time;
frame.render_role_enter_ns = render_role_enter_ns ? render_role_enter_ns : submit_time;
frame.core_data_time_ns = latest_input_time_ns.load(std::memory_order_acquire);
@@ -86,18 +74,16 @@ public:
frame.viewport_version = context->viewport_version.load(std::memory_order_acquire);
frame.wait_21_ns = submit_time > frame.render_role_enter_ns ? submit_time - frame.render_role_enter_ns : 0;
frame.render_begin_ns = submit_time;
std::uint64_t previous_render_state_version = pipeline.render_state_version;
pipeline.job_state = Plot_Render_Job_State::Running;
pipeline.render_state_version = frame.input_version;
std::uint64_t previous_render_state_version = pipeline.rendered_edit_version;
pipeline.render_job_state = Frame_Job_State::Running;
pipeline.rendered_edit_version = frame.input_version;
auto job = std::make_shared<Frame_Render_Job>();
job->owner = shared_from_this();
job->generation = generation.load(std::memory_order_acquire);
job->frame_lease = std::move(frame_lease);
job->buffer = buffer;
job->lifecycle = frame_record;
job->worker_stat = std::make_shared<Frame_Worker_Stat>();
job->worker_stat = std::make_shared<Frame_Worker_Stats>();
job->render_snapshot.context = context;
job->render_snapshot.size = size;
job->render_snapshot.background_color = background_color();
@@ -106,7 +92,6 @@ public:
job->render_snapshot.frame_metadata = frame_record.get();
job->render_snapshot.frame_update_states = &buffer->presented_update_states;
previous_frame_time_ns = submit_time;
job->renderables = renderable_tree_snapshot();
auto& scheduler = Global::instance()->render_scheduler();
bool submitted = scheduler.try_submit_render_task(Render_Executor_Task{
@@ -140,21 +125,18 @@ public:
});
if (submitted)
return true;
frame.outcome = Frame_Outcome::Worker_Budget_Dropped;
frame.worker.rejected_task_count++;
job->frame_lease.reset();
pipeline.render_state_version = previous_render_state_version;
pipeline.job_state = Plot_Render_Job_State::Idle;
pipeline.rendered_edit_version = previous_render_state_version;
pipeline.render_job_state = Frame_Job_State::Idle;
collect_frame(frame_record);
trigger_refresh_strategy(Refresh_Trigger::Render_Finished, &frame);
return false;
}
static bool frame_job_valid(const std::shared_ptr<Frame_Render_Job>& job) {
return job && job->buffer && job->lifecycle && job->render_snapshot.context && !job->render_snapshot.destroying();
}
void prepare_frame_job(const std::shared_ptr<Frame_Render_Job>& job) {
if (!frame_job_valid(job))
return;
@@ -170,7 +152,6 @@ public:
frame.prepare_end_ns = steady_now_ns();
job->render_snapshot.context->first_prepare_data.store(false, std::memory_order_release);
}
void draw_frame_job(const std::shared_ptr<Frame_Render_Job>& job) {
if (!frame_job_valid(job) || !job->lifecycle->prepare_end_ns)
return;
@@ -178,14 +159,12 @@ public:
job->buffer->image.resize(job->render_snapshot.size.width, job->render_snapshot.size.height);
job->buffer->image.fill(job->render_snapshot.background_color);
Canvas canvas(job->buffer->image);
frame.draw_begin_ns = steady_now_ns();
if (!job->renderables.empty() && job->renderables.front().renderable)
job->renderables.front().renderable->render_tree_snapshot(canvas, job->render_snapshot, job->renderables, 0);
frame.draw_end_ns = steady_now_ns();
frame.render_end_ns = steady_now_ns();
}
void finalize_frame_job(const std::shared_ptr<Frame_Render_Job>& job) {
if (!frame_job_valid(job) || !job->lifecycle->render_end_ns)
return;
@@ -196,7 +175,6 @@ public:
update_state->complete_until(Update_Stage::Rendered);
}
}
void execute_frame_job(const std::shared_ptr<Frame_Render_Job>& job) {
if (!job || !job->buffer || !job->lifecycle || !job->render_snapshot.context || job->render_snapshot.destroying())
return;
@@ -204,7 +182,6 @@ public:
draw_frame_job(job);
finalize_frame_job(job);
}
void complete_frame_job(const std::shared_ptr<Frame_Render_Job>& job) {
if (!job || !job->buffer || !job->lifecycle)
return;
@@ -216,27 +193,24 @@ public:
job->frame_lease.reset();
if (!valid_generation || !valid_context || !frame.render_end_ns) {
frame.outcome = Frame_Outcome::Cancelled;
pipeline.job_state = Plot_Render_Job_State::Idle;
pipeline.render_job_state = Frame_Job_State::Idle;
supersede_update_states(job->buffer->presented_update_states);
trigger_refresh_strategy(Refresh_Trigger::Render_Finished, &frame);
return;
}
auto publish_result = pipeline.try_publish_rendered(steady_now_ns());
if (publish_result.superseded_middle) {
trigger_refresh_strategy(Refresh_Trigger::Frame_Returned, publish_result.superseded_middle.get());
collect_frame(publish_result.superseded_middle);
auto publish_result = pipeline.try_publish_rendered_frame(steady_now_ns());
if (publish_result.superseded_frame_record) {
trigger_refresh_strategy(Refresh_Trigger::Frame_Returned, publish_result.superseded_frame_record.get());
collect_frame(publish_result.superseded_frame_record);
}
if (publish_result.dropped_frame) {
collect_frame(publish_result.dropped_frame);
if (publish_result.dropped_frame_record) {
collect_frame(publish_result.dropped_frame_record);
}
pipeline.job_state = Plot_Render_Job_State::Idle;
pipeline.render_job_state = Frame_Job_State::Idle;
if (publish_result.request_present)
request_present(publish_result.dirty_rect);
trigger_refresh_strategy(Refresh_Trigger::Render_Finished, &frame);
}
void post_scheduler_action(Task task) {
if (!task)
return;
@@ -253,7 +227,6 @@ public:
}
scheduler.post(std::move(action));
}
void trigger_refresh_strategy(Refresh_Trigger trigger, Frame_Lifecycle_Record* frame = nullptr) {
if (!strategy)
return;
@@ -262,7 +235,6 @@ public:
Refresh_Action action = strategy->on_trigger(trigger, runtime, frame);
apply_refresh_action(action, runtime);
}
void notify_input_changed(std::uint64_t now_ns) {
if (!strategy)
return;
@@ -270,7 +242,6 @@ public:
Refresh_Action action = strategy->on_trigger(Refresh_Trigger::Input_Dirty, runtime, nullptr);
apply_refresh_action(action, runtime);
}
void notify_started() {
if (!strategy_started) {
strategy_started = true;
@@ -280,7 +251,6 @@ public:
trigger_refresh_strategy(Refresh_Trigger::Input_Dirty);
}
}
void notify_paused() {
invalidate_refresh_deadline();
if (!strategy_started)
@@ -288,17 +258,15 @@ public:
strategy_started = false;
trigger_refresh_strategy(Refresh_Trigger::Paused);
}
void notify_frame_returned(std::shared_ptr<Frame_Lifecycle_Record> frame) {
if (!frame)
return;
trigger_refresh_strategy(Refresh_Trigger::Frame_Returned, frame.get());
collect_frame(frame);
}
void apply_refresh_action(Refresh_Action action, const Refresh_Runtime_Snapshot& runtime) {
if (action.request_paint) {
auto update_result = pipeline.request_paint_update(steady_now_ns());
auto update_result = pipeline.request_present(steady_now_ns());
if (update_result.request_present)
request_present(update_result.dirty_rect);
}
@@ -314,7 +282,6 @@ public:
if (!runtime.enabled || runtime.destroying || !runtime.dirty)
invalidate_refresh_deadline();
}
void schedule_refresh_deadline(std::uint64_t deadline_ns) {
if (deadline_ns <= steady_now_ns()) {
invalidate_refresh_deadline();
@@ -336,12 +303,10 @@ public:
self->trigger_refresh_strategy(Refresh_Trigger::Timer_Fired);
});
}
void invalidate_refresh_deadline() {
scheduled_refresh_deadline_ns = 0;
++refresh_deadline_generation;
}
void dispatch_event(const Event& event) {
if (!root)
return;
@@ -376,26 +341,22 @@ public:
break;
}
}
std::vector<std::shared_ptr<Renderable>> renderable_snapshot() const {
std::vector<std::shared_ptr<Renderable>> result;
append_renderable_snapshot(result, root);
return result;
}
Renderable_Tree_Snapshot renderable_tree_snapshot() const {
Renderable_Tree_Snapshot result;
if (root)
root->append_tree_snapshot(result);
return result;
}
std::vector<std::shared_ptr<Renderable>> reverse_renderable_snapshot() const {
std::vector<std::shared_ptr<Renderable>> result = renderable_snapshot();
std::reverse(result.begin(), result.end());
return result;
}
void append_renderable_snapshot(std::vector<std::shared_ptr<Renderable>>& result, const std::shared_ptr<Renderable>& renderable) const {
if (!renderable)
return;
@@ -403,7 +364,6 @@ public:
for (const auto& child : renderable->children_snapshot())
append_renderable_snapshot(result, child);
}
void dispatch_to_renderables(const std::vector<std::shared_ptr<Renderable>>& renderables, const Event& event) {
for (const auto& renderable : renderables) {
if (!renderable || event.is_accepted())
@@ -411,7 +371,6 @@ public:
renderable->plot_event(event);
}
}
void update_hover_targets(const Pointer_Event& event) {
Point pos{static_cast<int>(event.position.x), static_cast<int>(event.position.y)};
std::vector<std::shared_ptr<Renderable>> hits = root->hit_renderables(event.position);
@@ -431,7 +390,6 @@ public:
hover_targets.push_back(target);
}
}
void clear_hover_targets() {
Point pos{};
for (const auto& old_target : hover_targets) {
@@ -440,12 +398,10 @@ public:
}
hover_targets.clear();
}
void request_present(Rect dirty_rect) {
if (auto target = sink.lock())
target->request_present(dirty_rect);
}
void collect_frame(std::shared_ptr<const Frame_Lifecycle_Record> frame) {
if (!frame)
return;
@@ -453,12 +409,10 @@ public:
if (observer && observer->enabled())
observer->collect_frame(frame);
}
Color background_color() const {
Pixel p = context->background_rgba.load(std::memory_order_acquire);
return premultiplied_to_color(p);
}
std::unique_ptr<Refresh_Strategy> strategy;
std::shared_ptr<Plot_Render_Context> context = std::make_shared<Plot_Render_Context>();
std::shared_ptr<Renderable> root;
@@ -477,21 +431,18 @@ public:
Plot_Execution_Id plot_execution_id{};
std::atomic<std::uint64_t> generation{1};
};
namespace {
Plot_Execution_Id next_plot_execution_id() {
static std::atomic<Plot_Execution_Id> next_id{1};
return next_id.fetch_add(1, std::memory_order_acq_rel);
}
} // namespace
Plot_Core::Plot_Core(std::unique_ptr<Refresh_Strategy> strategy)
: d(std::make_shared<Plot_Core_Private>(std::move(strategy))) {
d->plot_execution_id = next_plot_execution_id();
d->context->owner.store(this, std::memory_order_release);
Global::instance()->render_scheduler().register_plot(this);
}
Plot_Core::~Plot_Core() {
d->destroying_flag.store(true, std::memory_order_release);
d->context->destroying.store(true, std::memory_order_release);
@@ -500,7 +451,6 @@ Plot_Core::~Plot_Core() {
d->pipeline.cancel_all_update_states();
d->context->owner.store(nullptr, std::memory_order_release);
}
void Plot_Core::init() {
if (!d->root) {
d->root = std::make_shared<Renderable>();
@@ -509,15 +459,12 @@ void Plot_Core::init() {
}
d->context->first_resize.store(true, std::memory_order_release);
}
std::shared_ptr<Plot_Render_Context> Plot_Core::render_context() const {
return d->context;
}
std::shared_ptr<Renderable> Plot_Core::root_renderable() const {
return d->root;
}
std::shared_ptr<Renderable> Plot_Core::create_renderable_node(
const std::shared_ptr<Renderable>& parent, std::string object_name) {
if (!parent)
@@ -527,7 +474,6 @@ std::shared_ptr<Renderable> Plot_Core::create_renderable_node(
node->init(parent);
return node;
}
void Plot_Core::remove_renderable(const std::shared_ptr<Renderable>& renderable) {
if (!renderable)
return;
@@ -537,16 +483,13 @@ void Plot_Core::remove_renderable(const std::shared_ptr<Renderable>& renderable)
renderable->detach_from_parent();
mark_render_state_dirty();
}
void Plot_Core::set_background_color(Color color) {
d->context->background_rgba.store(premultiply(color), std::memory_order_release);
mark_render_state_dirty();
}
Color Plot_Core::background_color() const {
return d->background_color();
}
void Plot_Core::set_viewport_size(Size size) {
Size previous{
d->context->render_width.load(std::memory_order_acquire),
@@ -559,30 +502,26 @@ void Plot_Core::set_viewport_size(Size size) {
if (!size.empty())
d->context->first_resize.store(false, std::memory_order_release);
}
Size Plot_Core::viewport_size() const {
return {
d->context->render_width.load(std::memory_order_acquire),
d->context->render_height.load(std::memory_order_acquire)
};
}
void Plot_Core::dispatch_event(const Event& event) {
d->dispatch_event(event);
}
void Plot_Core::mark_render_state_dirty() {
if (d->destroying_flag.load(std::memory_order_acquire))
return;
std::uint64_t now_ns = steady_now_ns();
d->pipeline.mark_edit_state();
d->pipeline.advance_edit_version();
d->latest_input_time_ns.store(now_ns, std::memory_order_release);
d->pending_input_count.fetch_add(1, std::memory_order_relaxed);
d->post_scheduler_action([data = d, now_ns]() {
data->notify_input_changed(now_ns);
});
}
void Plot_Core::request_manual_refresh() {
if (d->destroying_flag.load(std::memory_order_acquire))
return;
@@ -590,7 +529,6 @@ void Plot_Core::request_manual_refresh() {
data->trigger_refresh_strategy(Refresh_Trigger::Manual_Request);
});
}
void Plot_Core::start_render() {
if (d->destroying_flag.load(std::memory_order_acquire))
return;
@@ -599,34 +537,30 @@ void Plot_Core::start_render() {
data->notify_started();
});
}
void Plot_Core::pause_render() {
d->rendering.store(false, std::memory_order_release);
d->post_scheduler_action([data = d]() {
data->notify_paused();
});
}
bool Plot_Core::is_rendering() const {
return d->rendering.load(std::memory_order_acquire);
}
void Plot_Core::set_presentation_sink(std::weak_ptr<Presentation_Sink> sink) {
d->sink = std::move(sink);
}
Present_Frame Plot_Core::begin_present() {
Present_Frame result;
Present_Frame_Lease Plot_Core::begin_present() {
Present_Frame_Lease result;
if (!d->root)
return result;
auto consumed = d->pipeline.try_begin_paint(steady_now_ns());
if (consumed.returned_frame) {
d->post_scheduler_action([data = d, frame = consumed.returned_frame]() mutable {
auto consumed = d->pipeline.try_acquire_paint_frame(steady_now_ns());
if (consumed.returned_frame_record) {
d->post_scheduler_action([data = d, frame = consumed.returned_frame_record]() mutable {
data->notify_frame_returned(frame);
});
}
result.is_new_frame = consumed.new_frame;
result.update_was_pending = consumed.update_was_pending;
result.is_new_frame = consumed.has_new_frame;
result.update_was_pending = consumed.present_request_was_pending;
if (consumed.lease)
result.lease_ = std::make_unique<Plot_Frame_Lease>(std::move(consumed.lease));
if (!result.new_frame() && result.request_was_pending()) {
@@ -636,8 +570,7 @@ Present_Frame Plot_Core::begin_present() {
}
return result;
}
void Plot_Core::end_present(Present_Frame&& frame, std::uint64_t paint_begin_ns, std::uint64_t paint_end_ns) {
void Plot_Core::end_present(Present_Frame_Lease&& frame, std::uint64_t paint_begin_ns, std::uint64_t paint_end_ns) {
if (frame.lease_ && frame.lease_->frame) {
auto* rendered_frame = frame.lease_->frame;
if (rendered_frame->metadata) {
@@ -652,5 +585,4 @@ void Plot_Core::end_present(Present_Frame&& frame, std::uint64_t paint_begin_ns,
data->trigger_refresh_strategy(Refresh_Trigger::Paint_Finished);
});
}
} // namespace renderive