大重构改完

This commit is contained in:
2026-08-12 21:31:02 +08:00
parent 7c00b8565d
commit 15c3d21f2d
73 changed files with 4303 additions and 1727 deletions
@@ -8,7 +8,7 @@
#include "renderive/scene/Scene.hpp"
struct Renderable_Base_Test_Renderable : Renderable_Base {
Renderable_Base_Test_Renderable(Scene_Base& scene, bool cache_enabled) : Renderable_Base(scene, {.cache_enabled = cache_enabled}) {}
void render(const Scene_Render_Context&) override {
void prepare(const Scene_Render_Context&) override {
++render_count;
}
int render_count{};
@@ -35,7 +35,7 @@ TEST(renderable_base_test, controls_cache_with_configuration) {
scene.wait_for_render();
EXPECT_EQ(cached->render_count, 1);
EXPECT_EQ(uncached->render_count, 2);
cached->invalidate_cache();
cached->invalidate_prepare();
scene.render();
scene.wait_for_render();
EXPECT_EQ(cached->render_count, 2);
@@ -55,7 +55,7 @@ TEST(renderable_base_test, changes_configuration_through_scene) {
}
struct Renderable_Base_Cache_Invalidation_Test_Renderable : Renderable_Base {
explicit Renderable_Base_Cache_Invalidation_Test_Renderable(Scene_Base& scene) : Renderable_Base(scene, {.cache_enabled = true}) {}
void render(const Scene_Render_Context&) override {
void prepare(const Scene_Render_Context&) override {
const int count = render_count.fetch_add(1, std::memory_order_acq_rel) + 1;
if (count != 1) {
return;
@@ -90,18 +90,18 @@ TEST(renderable_base_test, preserves_cache_invalidation_that_happens_during_rend
scene.attach_renderable(renderable);
scene.render();
renderable->wait_started();
renderable->invalidate_cache();
renderable->invalidate_prepare();
renderable->release();
scene.wait_for_render();
EXPECT_FALSE(renderable->cache_valid());
EXPECT_FALSE(renderable->prepare_cache_valid());
scene.render();
scene.wait_for_render();
EXPECT_EQ(renderable->render_count.load(std::memory_order_acquire), 2);
EXPECT_TRUE(renderable->cache_valid());
EXPECT_TRUE(renderable->prepare_cache_valid());
}
struct Renderable_Base_Task_Graph_Rebuild_Test_Renderable : Renderable_Base {
explicit Renderable_Base_Task_Graph_Rebuild_Test_Renderable(Scene_Base& scene) : Renderable_Base(scene) {}
void build_task_graph(Renderable_Task_Graph& graph) override {
struct Renderable_Base_Render_Graph_Rebuild_Test_Renderable : Renderable_Base {
explicit Renderable_Base_Render_Graph_Rebuild_Test_Renderable(Scene_Base& scene) : Renderable_Base(scene) {}
void build_prepare_graph(Renderable_Graph_Builder& graph) override {
const int count = build_count.fetch_add(1, std::memory_order_acq_rel) + 1;
if (count == 1) {
std::unique_lock lock(mutex);
@@ -111,7 +111,8 @@ struct Renderable_Base_Task_Graph_Rebuild_Test_Renderable : Renderable_Base {
return release_build;
});
}
graph.emplace([](const Scene_Render_Context&) {}, "graph_rebuild_test");
graph.emplace("prepare", "graph_rebuild_test", Render_Node_Kind::prepare,
[](const Scene_Render_Context&) {});
}
void wait_build_started() {
std::unique_lock lock(mutex);
@@ -124,50 +125,56 @@ struct Renderable_Base_Task_Graph_Rebuild_Test_Renderable : Renderable_Base {
release_build = true;
condition.notify_all();
}
std::shared_ptr<const Renderable_Graph> graph_snapshot() {
return render_graph();
}
void request_graph_rebuild() noexcept {
rebuild_render_graph();
}
std::atomic<int> build_count{};
std::mutex mutex;
std::condition_variable condition;
bool build_started{};
bool release_build{};
};
TEST(renderable_base_test, preserves_rebuild_request_that_arrives_during_task_graph_build) {
TEST(renderable_base_test, preserves_rebuild_request_that_arrives_during_render_graph_build) {
Scene2D_Context<> scene;
Renderable_Base_Task_Graph_Rebuild_Test_Renderable renderable(scene);
std::shared_ptr<const Renderable_Task_Graph> first_graph;
Renderable_Base_Render_Graph_Rebuild_Test_Renderable renderable(scene);
std::shared_ptr<const Renderable_Graph> first_graph;
std::thread builder([&] {
first_graph = renderable.task_graph();
first_graph = renderable.graph_snapshot();
});
renderable.wait_build_started();
std::thread rebuilder([&] {
renderable.rebuild_task_graph();
renderable.request_graph_rebuild();
});
renderable.release();
builder.join();
rebuilder.join();
const auto second_graph = renderable.task_graph();
const auto second_graph = renderable.graph_snapshot();
EXPECT_EQ(renderable.build_count.load(std::memory_order_acquire), 2);
EXPECT_NE(first_graph.get(), second_graph.get());
}
TEST(renderable_base_test, task_graph_snapshots_remain_valid_during_concurrent_rebuilds) {
TEST(renderable_base_test, render_graph_snapshots_remain_valid_during_concurrent_rebuilds) {
Scene2D_Context<> scene;
Renderable_Base_Task_Graph_Rebuild_Test_Renderable renderable(scene);
Renderable_Base_Render_Graph_Rebuild_Test_Renderable renderable(scene);
renderable.release();
std::atomic<bool> running{true};
std::thread rebuilder([&] {
for (int index = 0; index < 500; ++index) {
renderable.rebuild_task_graph();
renderable.request_graph_rebuild();
}
running.store(false, std::memory_order_release);
});
while (running.load(std::memory_order_acquire)) {
const auto graph = renderable.task_graph();
const auto graph = renderable.graph_snapshot();
ASSERT_TRUE(graph);
EXPECT_EQ(graph->nodes().size(), 1);
EXPECT_EQ(graph->graph.nodes.size(), 1);
}
rebuilder.join();
const auto graph = renderable.task_graph();
const auto graph = renderable.graph_snapshot();
ASSERT_TRUE(graph);
EXPECT_EQ(graph->nodes().size(), 1);
EXPECT_EQ(graph->graph.nodes.size(), 1);
}
TEST(renderable_base_test, configuration_snapshot_is_safe_during_scene_updates) {
Scene2D_Context<> scene;