builder 和 运行时修改隔离开

This commit is contained in:
2026-08-13 11:25:38 +08:00
parent 9e598a0318
commit 4a48e62aea
57 changed files with 1512 additions and 2592 deletions
@@ -10,13 +10,14 @@
#include <thread>
#include "renderive/renderable/Renderable.hpp"
#include "renderive/scene/Scene.hpp"
#include "Scene_Test_Helpers.hpp"
namespace {
class Pipeline_Renderable : public Renderable_Base {
public:
explicit Pipeline_Renderable(Scene_Base& scene, bool cached = false)
: Renderable_Base(scene, {.cache_enabled = cached}) {}
explicit Pipeline_Renderable(bool cached = false)
: Renderable_Base({.cache_enabled = cached}) {}
std::function<void()> prepare_action;
std::function<void()> paint_action;
std::atomic<int> prepare_count{};
@@ -44,7 +45,7 @@ protected:
class Dynamic_Renderable : public Renderable_Base {
public:
explicit Dynamic_Renderable(Scene_Base& scene) : Renderable_Base(scene) {}
explicit Dynamic_Renderable() : Renderable_Base() {}
void set_chunk_count(std::size_t count) {
chunk_count_ = count;
rebuild_render_graph();
@@ -91,12 +92,14 @@ bool has_edge(const Render_Plan& plan, Render_Node_Id from, Render_Node_Id to) {
TEST(render_plan_execution_test, dependency_edges_connect_prepare_only_and_layer_edges_connect_composite) {
Scene2D_Context<> scene;
auto parent = std::make_shared<Pipeline_Renderable>(scene);
auto child = std::make_shared<Pipeline_Renderable>(scene);
scene.attach_renderable(parent);
scene.attach_renderable(child);
scene.set_parent(Scene_Base::Relationship::dependency, child, parent);
scene.set_parent(Scene_Base::Relationship::display, child, parent);
auto parent = renderive_Owner<Pipeline_Renderable>::make();
auto child = renderive_Owner<Pipeline_Renderable>::make();
with_attach_builder(scene, [&](auto& attach) {
attach.attach(parent);
attach.attach(child);
attach.set_parent(Scene_Base::Relationship::dependency, child, parent);
attach.set_parent(Scene_Base::Relationship::display, child, parent);
});
scene.render();
scene.wait_for_render();
@@ -115,8 +118,8 @@ TEST(render_plan_execution_test, dependency_edges_connect_prepare_only_and_layer
#ifndef RENDERIVE_TASKFLOW_MOCK
TEST(render_plan_execution_test, local_paint_can_run_while_an_unrelated_prepare_is_blocked) {
Scene2D_Context<> scene;
auto fast = std::make_shared<Pipeline_Renderable>(scene);
auto slow = std::make_shared<Pipeline_Renderable>(scene);
auto fast = renderive_Owner<Pipeline_Renderable>::make();
auto slow = renderive_Owner<Pipeline_Renderable>::make();
std::mutex mutex;
std::condition_variable condition;
bool slow_prepare_started{};
@@ -129,8 +132,7 @@ TEST(render_plan_execution_test, local_paint_can_run_while_an_unrelated_prepare_
condition.wait(lock, [&] { return release_slow; });
};
fast->paint_action = [&] { fast_painted.store(true, std::memory_order_release); };
scene.attach_renderable(fast);
scene.attach_renderable(slow);
attach_initial(scene, fast, slow);
scene.render();
{
std::unique_lock lock(mutex);
@@ -150,8 +152,8 @@ TEST(render_plan_execution_test, local_paint_can_run_while_an_unrelated_prepare_
TEST(render_plan_execution_test, dependent_prepare_does_not_wait_for_dependency_paint) {
Scene2D_Context<> scene;
auto parent = std::make_shared<Pipeline_Renderable>(scene);
auto child = std::make_shared<Pipeline_Renderable>(scene);
auto parent = renderive_Owner<Pipeline_Renderable>::make();
auto child = renderive_Owner<Pipeline_Renderable>::make();
std::mutex mutex;
std::condition_variable condition;
bool parent_paint_started{};
@@ -164,9 +166,11 @@ TEST(render_plan_execution_test, dependent_prepare_does_not_wait_for_dependency_
condition.wait(lock, [&] { return release_parent_paint; });
};
child->prepare_action = [&] { child_prepared.store(true, std::memory_order_release); };
scene.attach_renderable(parent);
scene.attach_renderable(child);
scene.set_parent(Scene_Base::Relationship::dependency, child, parent);
with_attach_builder(scene, [&](auto& attach) {
attach.attach(parent);
attach.attach(child);
attach.set_parent(Scene_Base::Relationship::dependency, child, parent);
});
scene.render();
{
std::unique_lock lock(mutex);
@@ -187,8 +191,8 @@ TEST(render_plan_execution_test, dependent_prepare_does_not_wait_for_dependency_
TEST(render_plan_execution_test, prepare_and_paint_cache_validity_are_independent_and_prune_nodes) {
Scene2D_Context<> scene;
auto renderable = std::make_shared<Pipeline_Renderable>(scene, true);
scene.attach_renderable(renderable);
auto renderable = renderive_Owner<Pipeline_Renderable>::make(true);
attach_initial(scene, renderable);
scene.render();
scene.wait_for_render();
EXPECT_TRUE(renderable->prepare_cache_valid());
@@ -239,8 +243,8 @@ TEST(render_plan_execution_test, prepare_and_paint_cache_validity_are_independen
TEST(render_plan_execution_test, logical_node_ids_are_stable_and_retired_ids_are_never_reused) {
Scene_Base scene;
auto renderable = std::make_shared<Dynamic_Renderable>(scene);
scene.attach_renderable(renderable);
auto renderable = renderive_Owner<Dynamic_Renderable>::make();
attach_initial(scene, renderable);
const auto first = renderable->graph_snapshot();
ASSERT_EQ(first->graph.nodes.size(), 3u);
const Render_Node_Id root = first->graph.nodes[0].node_id;
@@ -276,8 +280,8 @@ TEST(render_plan_execution_test, logical_node_ids_are_stable_and_retired_ids_are
TEST(render_plan_execution_test, capture_off_keeps_abstract_frame_without_execution_timing) {
Scene2D_Context<> scene;
auto renderable = std::make_shared<Pipeline_Renderable>(scene);
scene.attach_renderable(renderable);
auto renderable = renderive_Owner<Pipeline_Renderable>::make();
attach_initial(scene, renderable);
Abstract_Frame frame;
scene.render(frame);
scene.wait_for_render();
@@ -286,8 +290,8 @@ TEST(render_plan_execution_test, capture_off_keeps_abstract_frame_without_execut
TEST(render_plan_execution_test, measures_capture_off_and_on_cost_separately) {
Scene2D_Context<> scene;
auto renderable = std::make_shared<Pipeline_Renderable>(scene);
scene.attach_renderable(renderable);
auto renderable = renderive_Owner<Pipeline_Renderable>::make();
attach_initial(scene, renderable);
constexpr std::size_t warmup_count = 32;
constexpr std::size_t frame_count = 512;
const auto render_frames = [&scene](std::size_t count) {
@@ -316,8 +320,8 @@ TEST(render_plan_execution_test, measures_capture_off_and_on_cost_separately) {
TEST(render_plan_execution_test, capture_requests_publish_exact_immutable_abstract_frame_snapshots) {
Scene2D_Context<> scene;
auto renderable = std::make_shared<Pipeline_Renderable>(scene, true);
scene.attach_renderable(renderable);
auto renderable = renderive_Owner<Pipeline_Renderable>::make(true);
attach_initial(scene, renderable);
constexpr std::size_t capture_count = 20;
const Capture_Session_Id session_id = scene.capture_frames(capture_count);
Alternate_Frame alternate_frame;
@@ -348,13 +352,13 @@ TEST(render_plan_execution_test, capture_requests_publish_exact_immutable_abstra
TEST(render_plan_execution_test, failed_render_discards_abstract_frame_capture_and_retries_ticket) {
Scene2D_Context<> scene;
auto renderable = std::make_shared<Pipeline_Renderable>(scene);
auto renderable = renderive_Owner<Pipeline_Renderable>::make();
std::atomic<bool> fail_once{true};
renderable->paint_action = [&] {
if (fail_once.exchange(false))
throw std::runtime_error("paint failed");
};
scene.attach_renderable(renderable);
attach_initial(scene, renderable);
const Capture_Session_Id session_id = scene.capture_next_frame();
Alternate_Frame failed_frame;
scene.render(failed_frame);