结构优化

This commit is contained in:
2026-08-13 15:17:02 +08:00
parent 65cf786e2d
commit e8e8b29806
25 changed files with 822 additions and 461 deletions
@@ -4,14 +4,16 @@
#include <thread>
#include <utility>
#include "renderive/renderable/Renderable.hpp"
#include "renderive/renderable/Renderable_Test_Harness.hpp"
#include "renderive/scene/Scene.hpp"
#include "Scene_Test_Helpers.hpp"
static_assert(std::same_as<decltype(std::declval<const Scene2D_Context<>&>().topology_snapshot()), Scene_Base::Topology_Snapshot>);
struct Scene2D_Context_Test_Renderable : Renderable_Base {
explicit Scene2D_Context_Test_Renderable() : Renderable_Base({.cache_enabled = false}) {}
void prepare(const Prepare_Render_Context&) override {
struct Scene2D_Context_Test_Renderable : Renderable_Test_Harness {
explicit Scene2D_Context_Test_Renderable()
: Renderable_Test_Harness({.cache_enabled = false}) {}
void prepare_for_test(const Prepare_Render_Context&) override {
++render_count;
scene_is_2d = dynamic_cast<Scene_2D_Base*>(&scene()) != nullptr;
scene_is_2d = dynamic_cast<Scene_2D_Base*>(&scene_for_test()) != nullptr;
render_thread = std::this_thread::get_id();
}
std::atomic<int> render_count{};
@@ -39,9 +41,10 @@ TEST(scene2d_context_test, swaps_renderable_cache_and_renders_in_background) {
EXPECT_EQ(second->render_count.load(), 1);
EXPECT_EQ(scene.frame_control_strategy().frame_control_state().publish_revision, 2);
}
struct Scene2D_Final_Cache_Blocking_Renderable : Renderable_Base {
explicit Scene2D_Final_Cache_Blocking_Renderable() : Renderable_Base({.cache_enabled = false}) {}
void prepare(const Prepare_Render_Context&) override {
struct Scene2D_Final_Cache_Blocking_Renderable : Renderable_Test_Harness {
explicit Scene2D_Final_Cache_Blocking_Renderable()
: Renderable_Test_Harness({.cache_enabled = false}) {}
void prepare_for_test(const Prepare_Render_Context&) override {
while (!release.load(std::memory_order_acquire)) {
started.store(true, std::memory_order_release);
std::this_thread::yield();
@@ -74,12 +77,13 @@ TEST(scene2d_context_test, final_color_cache_access_waits_for_render_completion)
reader.join();
EXPECT_TRUE(cache_accessed.load(std::memory_order_acquire));
}
struct Scene2D_Cached_Renderable : Renderable_Base {
Scene2D_Cached_Renderable(std::uint64_t value) : Renderable_Base({.cache_enabled = true}), value(value) {}
void prepare(const Prepare_Render_Context&) override {
struct Scene2D_Cached_Renderable : Renderable_Test_Harness {
Scene2D_Cached_Renderable(std::uint64_t value)
: Renderable_Test_Harness({.cache_enabled = true}), value(value) {}
void prepare_for_test(const Prepare_Render_Context&) override {
++render_count;
}
void build_paint_graph(Renderable_Graph_Builder& graph) override {
void build_paint_graph_for_test(Renderable_Graph_Builder& graph) override {
graph.emplace("paint", "Paint",
[this](const Paint_Render_Context& context) {
dynamic_cast<Recording_Color_Cache&>(context.color_cache).append(value);
@@ -116,7 +120,7 @@ TEST(scene2d_context_test, dependency_reparent_invalidates_cached_child) {
attach.attach(first_parent);
attach.attach(second_parent);
attach.attach(child);
attach.set_parent(Scene_Base::Relationship::dependency, child, first_parent);
attach.set_dependency_parent(child, first_parent);
});
scene.render();
scene.wait_for_render();
@@ -124,7 +128,7 @@ TEST(scene2d_context_test, dependency_reparent_invalidates_cached_child) {
EXPECT_EQ(second_parent->render_count, 1);
EXPECT_EQ(child->render_count, 1);
wait_renderable_edit(scene, [child, second_parent](auto& editor) {
editor.set_parent(Scene_Base::Relationship::dependency, child, second_parent);
editor.set_dependency_parent(child, second_parent);
});
scene.render();
scene.wait_for_render();
@@ -141,17 +145,17 @@ TEST(scene2d_context_test, multiple_dependency_parents_invalidate_cached_child)
attach.attach(first_parent);
attach.attach(second_parent);
attach.attach(child);
attach.set_parent(Scene_Base::Relationship::dependency, child, first_parent);
attach.add_parent(Scene_Base::Relationship::dependency, child, second_parent);
attach.set_dependency_parent(child, first_parent);
attach.add_dependency_parent(child, second_parent);
});
scene.render();
scene.wait_for_render();
EXPECT_EQ(child->render_count, 1);
first_parent->invalidate_prepare();
first_parent->invalidate_prepare_for_test();
scene.render();
scene.wait_for_render();
EXPECT_EQ(child->render_count, 2);
second_parent->invalidate_prepare();
second_parent->invalidate_prepare_for_test();
scene.render();
scene.wait_for_render();
EXPECT_EQ(child->render_count, 3);
@@ -170,9 +174,9 @@ TEST(scene2d_context_test, final_color_cache_callback_can_reenter_scene_control_
scene.render();
scene.wait_for_render();
scene.with_final_color_cache([&](const Recording_Color_Cache&) {
renderable->set_configuration({.cache_enabled = false});
renderable->set_configuration_for_test({.cache_enabled = false});
});
EXPECT_FALSE(renderable->configuration().cache_enabled);
EXPECT_FALSE(renderable->configuration_for_test().cache_enabled);
}
TEST(scene2d_context_test, detach_dependency_parent_invalidates_promoted_cached_child) {
Scene2D_Context<> scene;
@@ -183,8 +187,8 @@ TEST(scene2d_context_test, detach_dependency_parent_invalidates_promoted_cached_
attach.attach(grandparent);
attach.attach(parent);
attach.attach(child);
attach.set_parent(Scene_Base::Relationship::dependency, parent, grandparent);
attach.set_parent(Scene_Base::Relationship::dependency, child, parent);
attach.set_dependency_parent(parent, grandparent);
attach.set_dependency_parent(child, parent);
});
scene.render();
scene.wait_for_render();
@@ -192,9 +196,9 @@ TEST(scene2d_context_test, detach_dependency_parent_invalidates_promoted_cached_
EXPECT_EQ(parent->render_count, 1);
EXPECT_EQ(child->render_count, 1);
wait_renderable_edit(scene, [grandparent, parent, child](auto& editor) {
editor.clear_parents(Scene_Base::Relationship::dependency, child);
editor.clear_parents(Scene_Base::Relationship::dependency, parent);
editor.set_parent(Scene_Base::Relationship::dependency, child, grandparent);
editor.clear_dependency_parent(child);
editor.clear_dependency_parent(parent);
editor.set_dependency_parent(child, grandparent);
editor.detach(parent);
});
scene.render();
@@ -232,9 +236,9 @@ TEST(scene2d_context_test, failed_attach_leaves_renderable_fully_detached) {
EXPECT_NO_THROW(attach_initial(scene, renderable));
EXPECT_EQ(scene.renderable_count(), 1);
}
struct Scene2D_Viewport_Snapshot_Renderable : Renderable_Base {
explicit Scene2D_Viewport_Snapshot_Renderable() : Renderable_Base() {}
void prepare(const Prepare_Render_Context& context) override {
struct Scene2D_Viewport_Snapshot_Renderable : Renderable_Test_Harness {
explicit Scene2D_Viewport_Snapshot_Renderable() = default;
void prepare_for_test(const Prepare_Render_Context& context) override {
viewport = context.frame.viewport;
}
Frame_Viewport viewport;
@@ -250,7 +254,7 @@ TEST(scene2d_context_test, published_scene_viewport_is_frozen_for_render) {
scene.wait_for_render();
EXPECT_EQ(renderable->viewport, (Frame_Viewport{320, 180}));
scene.publish_frame_state();
renderable->invalidate_prepare();
renderable->invalidate_prepare_for_test();
scene.render();
scene.wait_for_render();
EXPECT_EQ(renderable->viewport, (Frame_Viewport{640, 360}));