策略抽离

This commit is contained in:
2026-08-02 16:02:15 +08:00
parent dda25f9038
commit ffaca5b05f
55 changed files with 1431 additions and 886 deletions
+43 -25
View File
@@ -1,9 +1,12 @@
#include "Plot_Core.h"
#include "Plot_Core_Access.h"
#include "../architecture/Renderable.h"
#include "../architecture/Plot_Render_Context.h"
#include "../architecture/Render_Time.h"
#include "../architecture/Update_Completion.h"
#include "../base/global.h"
#include "../render/Canvas.h"
#include "../render/Render_Frame_Snapshot.h"
#include <algorithm>
#include <memory>
#include <utility>
@@ -62,6 +65,7 @@ public:
frame.pixel_width = static_cast<std::uint64_t>(size.width);
frame.pixel_height = static_cast<std::uint64_t>(size.height);
frame.viewport_version = context->viewport_version.load(std::memory_order_acquire);
frame.dirty_reason_mask = pending_dirty_reason_mask.exchange(0, std::memory_order_acq_rel);
frame.render_queue_wait_ns = submit_time > frame.render_role_enter_ns ? submit_time - frame.render_role_enter_ns : 0;
frame.render_begin_ns = submit_time;
auto job = std::make_shared<Frame_Render_Job>();
@@ -71,7 +75,7 @@ public:
job->buffer = buffer;
job->lifecycle = frame_record;
job->worker_stat = std::make_shared<Frame_Worker_Stats>();
job->render_snapshot.context = context;
job->render_snapshot.destroying_token = destroying_token;
job->render_snapshot.size = size;
job->render_snapshot.background_color = background_color();
job->render_snapshot.previous_frame_time_ns = previous_frame_time_ns;
@@ -86,20 +90,20 @@ public:
frame.frame_id,
Render_Task_Kind::Frame,
Task{},
[job](tf::Taskflow& taskflow, tf::Task entry, tf::Task exit) {
auto prepare = taskflow.emplace([job]() {
[job](Render_Task_Graph& graph, Render_Task_Graph_Node entry, Render_Task_Graph_Node exit) {
auto prepare = graph.emplace(Task([job]() {
job->owner->prepare_frame_job(job);
});
auto draw = taskflow.emplace([job]() {
}));
auto draw = graph.emplace(Task([job]() {
job->owner->draw_frame_job(job);
});
auto finalize = taskflow.emplace([job]() {
}));
auto finalize = graph.emplace(Task([job]() {
job->owner->finalize_frame_job(job);
});
entry.precede(prepare);
prepare.precede(draw);
draw.precede(finalize);
finalize.precede(exit);
}));
graph.precede(entry, prepare);
graph.precede(prepare, draw);
graph.precede(draw, finalize);
graph.precede(finalize, exit);
},
Task([job]() {
Global::instance()->render_scheduler().post([job]() {
@@ -121,7 +125,7 @@ public:
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();
return job && job->buffer && job->lifecycle && !job->render_snapshot.destroying();
}
void prepare_frame_job(const std::shared_ptr<Frame_Render_Job>& job) {
if (!frame_job_valid(job))
@@ -136,7 +140,8 @@ public:
++frame.prepared_output_count;
}
frame.prepare_end_ns = steady_now_ns();
job->render_snapshot.context->first_prepare_data.store(false, std::memory_order_release);
if (job->owner && job->owner->context)
job->owner->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)
@@ -161,7 +166,7 @@ public:
}
}
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())
if (!job || !job->buffer || !job->lifecycle || job->render_snapshot.destroying())
return;
prepare_frame_job(job);
draw_frame_job(job);
@@ -219,9 +224,9 @@ public:
if (update_result.request_present)
request_present(update_result.dirty_rect);
}
void notify_model_dirty(std::uint64_t now_ns) {
void notify_model_dirty(Dirty_Reason reason, std::uint64_t now_ns) {
if (flow)
flow->notify_model_dirty(now_ns);
flow->notify_model_dirty(reason, now_ns);
}
void notify_viewport_changed(Size viewport, std::uint64_t now_ns) {
if (flow)
@@ -385,11 +390,13 @@ public:
}
std::unique_ptr<Frame_Flow> flow;
std::shared_ptr<Plot_Render_Context> context = std::make_shared<Plot_Render_Context>();
std::shared_ptr<std::atomic_bool> destroying_token = std::make_shared<std::atomic_bool>(false);
std::shared_ptr<Renderable> root;
std::vector<std::weak_ptr<Renderable>> hover_targets;
std::weak_ptr<Presentation_Sink> sink;
std::atomic<std::uint64_t> latest_input_time_ns{0};
std::atomic<std::uint64_t> pending_input_count{0};
std::atomic<std::uint32_t> pending_dirty_reason_mask{0};
std::uint64_t flow_deadline_generation{};
std::uint64_t scheduled_flow_deadline_ns{};
std::uint64_t next_frame_id{};
@@ -413,6 +420,7 @@ Plot_Core::Plot_Core(std::unique_ptr<Frame_Flow> flow)
}
Plot_Core::~Plot_Core() {
d->context->destroying.store(true, std::memory_order_release);
d->destroying_token->store(true, std::memory_order_release);
d->generation.fetch_add(1, std::memory_order_acq_rel);
if (d->flow)
d->flow->shutdown();
@@ -429,9 +437,6 @@ 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;
}
@@ -455,7 +460,7 @@ void Plot_Core::remove_renderable(const std::shared_ptr<Renderable>& renderable)
}
void Plot_Core::set_background_color(Color color) {
d->context->background_rgba.store(premultiply(color), std::memory_order_release);
notify_model_dirty();
notify_model_dirty(Dirty_Reason::Config);
}
Color Plot_Core::background_color() const {
return d->background_color();
@@ -472,6 +477,7 @@ void Plot_Core::set_viewport_size(Size size) {
if (!size.empty())
d->context->first_resize.store(false, std::memory_order_release);
if (previous != size) {
d->pending_dirty_reason_mask.fetch_or(dirty_reason_bit(Dirty_Reason::Viewport), std::memory_order_acq_rel);
d->post_scheduler_action([data = d, size]() {
data->notify_viewport_changed(size, steady_now_ns());
});
@@ -486,23 +492,24 @@ Size Plot_Core::viewport_size() const {
void Plot_Core::dispatch_event(const Event& event) {
d->dispatch_event(event);
}
void Plot_Core::notify_model_dirty() {
void Plot_Core::notify_model_dirty(Dirty_Reason reason) {
if (d->destroying())
return;
std::uint64_t now_ns = steady_now_ns();
if (d->flow)
d->flow->advance_edit_version();
d->pending_dirty_reason_mask.fetch_or(dirty_reason_bit(reason), std::memory_order_acq_rel);
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_model_dirty(now_ns);
d->post_scheduler_action([data = d, reason, now_ns]() {
data->notify_model_dirty(reason, now_ns);
});
}
void Plot_Core::request_explicit_render() {
if (d->destroying())
return;
d->post_scheduler_action([data = d]() {
data->notify_model_dirty(steady_now_ns());
data->notify_model_dirty(Dirty_Reason::Core_Data, steady_now_ns());
});
}
void Plot_Core::activate_view() {
@@ -523,6 +530,9 @@ bool Plot_Core::view_active() const {
void Plot_Core::set_presentation_sink(std::weak_ptr<Presentation_Sink> sink) {
d->sink = std::move(sink);
}
Renderable_Runtime_Strategy Plot_Core::renderable_runtime_strategy() const {
return d->flow ? d->flow->renderable_runtime_strategy() : Renderable_Runtime_Strategy::Explicit;
}
Present_Surface_Lease Plot_Core::begin_present() {
Present_Surface_Lease result;
if (!d->root || !d->flow)
@@ -550,4 +560,12 @@ void Plot_Core::end_present(Present_Surface_Lease&& frame, std::uint64_t paint_b
data->notify_paint_finished();
});
}
std::shared_ptr<Plot_Render_Context> Plot_Core_Context_Access::render_context(Plot_Core& plot) {
return plot.d ? plot.d->context : std::shared_ptr<Plot_Render_Context>{};
}
std::shared_ptr<Plot_Render_Context> Plot_Core_Context_Access::render_context(const Plot_Core& plot) {
return plot.d ? plot.d->context : std::shared_ptr<Plot_Render_Context>{};
}
} // namespace renderive