策略抽离
This commit is contained in:
+43
-25
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user