闪烁问题解决

This commit is contained in:
2026-08-02 20:25:59 +08:00
parent 36d63efc7b
commit 7316f391d0
12 changed files with 381 additions and 34 deletions
+29 -6
View File
@@ -50,6 +50,7 @@ public:
if (!frame_surface)
return false;
Render_Output* buffer = frame_surface.output;
buffer->render_complete.store(false, std::memory_order_release);
cancel_update_states(buffer->presented_update_states);
if (flow)
flow->drain_frame_update_states(buffer->presented_update_states);
@@ -87,6 +88,16 @@ public:
previous_frame_time_ns = submit_time;
job->renderables = renderable_tree_snapshot();
job->render_snapshot.frame_tree = &job->renderables;
if (!frame_tree_views_complete(job->renderables)) {
frame.outcome = Frame_Outcome::Cancelled;
if (flow)
flow->cancel_render_frame(std::move(job->frame_surface));
supersede_update_states(buffer->presented_update_states);
release_frame_views(job);
collect_frame(frame_record);
notify_render_finished(frame);
return false;
}
auto& scheduler = Global::instance()->render_scheduler();
bool submitted = scheduler.try_submit_render_task(Render_Executor_Task{
plot_execution_id,
@@ -130,10 +141,22 @@ public:
frame.worker.rejected_task_count++;
if (flow)
flow->discard_render_frame(std::move(job->frame_surface));
release_frame_views(job);
collect_frame(frame_record);
notify_render_finished(frame);
return false;
}
static bool frame_tree_views_complete(const Renderable_Frame_Tree& tree) {
return std::all_of(tree.begin(), tree.end(), [](const Renderable_Frame_Node& node) {
return !node.frame_view_required || static_cast<bool>(node.frame_view);
});
}
static void release_frame_views(const std::shared_ptr<Frame_Render_Job>& job) {
if (!job)
return;
job->render_snapshot.frame_tree = nullptr;
job->renderables.clear();
}
static bool frame_job_valid(const std::shared_ptr<Frame_Render_Job>& job) {
return job && job->buffer && job->lifecycle && !job->render_snapshot.destroying();
}
@@ -174,6 +197,7 @@ public:
if (!frame_job_valid(job) || !job->lifecycle->prepare_end_ns)
return;
Frame_Lifecycle_Record& frame = *job->lifecycle;
job->buffer->render_complete.store(false, std::memory_order_release);
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);
@@ -191,6 +215,7 @@ public:
if (update_state)
update_state->complete_until(Update_Stage::Rendered);
}
job->buffer->render_complete.store(true, std::memory_order_release);
}
void execute_frame_job(const std::shared_ptr<Frame_Render_Job>& job) {
if (!job || !job->buffer || !job->lifecycle || job->render_snapshot.destroying())
@@ -210,15 +235,18 @@ public:
frame.worker = *job->worker_stat;
bool valid_generation = job->generation == generation.load(std::memory_order_acquire);
bool valid_context = !destroying();
if (!valid_generation || !valid_context || !frame.render_end_ns) {
bool render_complete = job->buffer->render_complete.load(std::memory_order_acquire);
if (!valid_generation || !valid_context || !frame.render_end_ns || !render_complete) {
if (flow)
flow->cancel_render_frame(std::move(job->frame_surface));
frame.outcome = Frame_Outcome::Cancelled;
supersede_update_states(job->buffer->presented_update_states);
release_frame_views(job);
notify_render_finished(frame);
return;
}
auto publish_result = flow ? flow->publish_rendered_frame(std::move(job->frame_surface), steady_now_ns()) : Render_Surface_Publish_Result{};
release_frame_views(job);
if (publish_result.superseded_frame_record) {
notify_frame_returned(publish_result.superseded_frame_record);
}
@@ -574,11 +602,6 @@ Present_Surface_Lease Plot_Core::begin_present() {
data->notify_frame_returned(frame);
});
}
if (!result.new_frame() && result.request_was_pending()) {
d->post_scheduler_action([data = d]() {
data->notify_paint_finished();
});
}
return result;
}
void Plot_Core::end_present(Present_Surface_Lease&& frame, std::uint64_t paint_begin_ns, std::uint64_t paint_end_ns) {