结构优化

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
@@ -5,15 +5,17 @@
#include <mutex>
#include <atomic>
#include "renderive/renderable/Renderable.hpp"
#include "renderive/renderable/Renderable_Test_Harness.hpp"
#include "renderive/scene/Scene.hpp"
struct Renderable_Base_Test_Renderable : Renderable_Base {
Renderable_Base_Test_Renderable(bool cache_enabled) : Renderable_Base({.cache_enabled = cache_enabled}) {}
void prepare(const Prepare_Render_Context&) override {
struct Renderable_Base_Test_Renderable : Renderable_Test_Harness {
Renderable_Base_Test_Renderable(bool cache_enabled)
: Renderable_Test_Harness({.cache_enabled = cache_enabled}) {}
void prepare_for_test(const Prepare_Render_Context&) override {
++render_count;
}
int render_count{};
};
TEST(renderable_base_test, exposes_scene_and_strategy_through_accessors) {
TEST(renderable_base_test, implementation_binds_scene_and_strategy) {
Scene2D_Context<> low_latency_scene;
Scene2D_Context<Manual_Refresh_Strategy<Scene2D_Frame_Data>> manual_scene;
auto low_latency_renderable = renderive_Owner<Renderable_Base_Test_Renderable>::make(true);
@@ -26,10 +28,16 @@ TEST(renderable_base_test, exposes_scene_and_strategy_through_accessors) {
auto attach = manual_scene.attach_builder();
attach.attach(manual_renderable);
}
EXPECT_EQ(&low_latency_renderable->scene(), &low_latency_scene);
EXPECT_EQ(&low_latency_renderable->scene().frame_control_strategy(), &low_latency_scene.frame_control);
EXPECT_DOUBLE_EQ(low_latency_renderable->scene().frame_control_strategy().frequency_hz(), 60.0);
EXPECT_TRUE(std::isnan(manual_renderable->scene().frame_control_strategy().frequency_hz()));
EXPECT_EQ(&low_latency_renderable->scene_for_test(), &low_latency_scene);
EXPECT_EQ(&low_latency_renderable->scene_for_test().frame_control_strategy(),
&low_latency_scene.frame_control);
EXPECT_DOUBLE_EQ(low_latency_renderable->scene_for_test()
.frame_control_strategy()
.frequency_hz(),
60.0);
EXPECT_TRUE(std::isnan(manual_renderable->scene_for_test()
.frame_control_strategy()
.frequency_hz()));
}
TEST(renderable_base_test, controls_cache_with_configuration) {
Scene2D_Context<> scene;
@@ -46,7 +54,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_prepare();
cached->invalidate_prepare_for_test();
scene.render();
scene.wait_for_render();
EXPECT_EQ(cached->render_count, 2);
@@ -61,15 +69,16 @@ TEST(renderable_base_test, changes_configuration_through_scene) {
}
scene.render();
scene.wait_for_render();
renderable->set_configuration({.cache_enabled = true});
renderable->set_configuration_for_test({.cache_enabled = true});
scene.render();
scene.wait_for_render();
EXPECT_TRUE(renderable->configuration().cache_enabled);
EXPECT_EQ(renderable->render_count, 1);
EXPECT_TRUE(renderable->configuration_for_test().cache_enabled);
EXPECT_EQ(renderable->render_count, 2);
}
struct Renderable_Base_Cache_Invalidation_Test_Renderable : Renderable_Base {
explicit Renderable_Base_Cache_Invalidation_Test_Renderable() : Renderable_Base({.cache_enabled = true}) {}
void prepare(const Prepare_Render_Context&) override {
struct Renderable_Base_Cache_Invalidation_Test_Renderable : Renderable_Test_Harness {
explicit Renderable_Base_Cache_Invalidation_Test_Renderable()
: Renderable_Test_Harness({.cache_enabled = true}) {}
void prepare_for_test(const Prepare_Render_Context&) override {
const int count = render_count.fetch_add(1, std::memory_order_acq_rel) + 1;
if (count != 1) {
return;
@@ -107,18 +116,18 @@ TEST(renderable_base_test, preserves_cache_invalidation_that_happens_during_rend
}
scene.render();
renderable->wait_started();
renderable->invalidate_prepare();
renderable->invalidate_prepare_for_test();
renderable->release();
scene.wait_for_render();
EXPECT_FALSE(renderable->prepare_cache_valid());
EXPECT_FALSE(renderable->prepare_cache_valid_for_test());
scene.render();
scene.wait_for_render();
EXPECT_EQ(renderable->render_count.load(std::memory_order_acquire), 2);
EXPECT_TRUE(renderable->prepare_cache_valid());
EXPECT_TRUE(renderable->prepare_cache_valid_for_test());
}
struct Renderable_Base_Render_Graph_Rebuild_Test_Renderable : Renderable_Base {
explicit Renderable_Base_Render_Graph_Rebuild_Test_Renderable() : Renderable_Base() {}
void build_prepare_graph(Renderable_Graph_Builder& graph) override {
struct Renderable_Base_Render_Graph_Rebuild_Test_Renderable : Renderable_Test_Harness {
explicit Renderable_Base_Render_Graph_Rebuild_Test_Renderable() = default;
void build_prepare_graph_for_test(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);
@@ -143,10 +152,10 @@ struct Renderable_Base_Render_Graph_Rebuild_Test_Renderable : Renderable_Base {
condition.notify_all();
}
std::shared_ptr<const Renderable_Graph> graph_snapshot() {
return render_graph();
return render_graph_for_test();
}
void request_graph_rebuild() {
rebuild_render_graph();
rebuild_render_graph_for_test();
}
std::atomic<int> build_count{};
std::mutex mutex;
@@ -201,14 +210,15 @@ TEST(renderable_base_test, configuration_snapshot_is_safe_during_scene_updates)
std::atomic<bool> running{true};
std::thread writer([&] {
for (int index = 0; index < 1000; ++index) {
renderable->set_configuration({.cache_enabled = index % 2 != 0});
renderable->set_configuration_for_test(
{.cache_enabled = index % 2 != 0});
}
running.store(false, std::memory_order_release);
});
while (running.load(std::memory_order_acquire)) {
const auto configuration = renderable->configuration();
const auto configuration = renderable->configuration_for_test();
static_cast<void>(configuration.cache_enabled);
}
writer.join();
EXPECT_TRUE(renderable->configuration().cache_enabled);
EXPECT_TRUE(renderable->configuration_for_test().cache_enabled);
}