核心模板架构
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "renderive/renderable/Renderable.hpp"
|
||||
#include "renderive/scene/Scene.hpp"
|
||||
struct Renderable_Task_Graph_Test_Renderable : Renderable_Base {
|
||||
Renderable_Task_Graph_Test_Renderable(Scene_Base& scene, std::vector<int>& order, int base)
|
||||
: Renderable_Base(scene, {.cache_enabled = false}), order(&order), base(base) {}
|
||||
void build_task_graph(Renderable_Task_Graph& graph) override {
|
||||
auto first = graph.emplace([this](const Scene_Render_Context&) {
|
||||
order->push_back(base + 1);
|
||||
}, "first");
|
||||
auto second = graph.emplace([this](const Scene_Render_Context&) {
|
||||
order->push_back(base + 2);
|
||||
}, "second");
|
||||
graph.precede(first, second);
|
||||
}
|
||||
std::vector<int>* order;
|
||||
int base;
|
||||
};
|
||||
TEST(renderable_task_graph_test, combines_internal_and_external_dependencies) {
|
||||
Scene2D_Context<> scene;
|
||||
std::vector<int> order;
|
||||
auto dependency = std::make_shared<Renderable_Task_Graph_Test_Renderable>(scene, order, 0);
|
||||
auto dependent = std::make_shared<Renderable_Task_Graph_Test_Renderable>(scene, order, 10);
|
||||
scene.attach_renderable(dependency);
|
||||
scene.attach_renderable(dependent);
|
||||
dependency->dependency_node.append_child(dependent->dependency_node);
|
||||
scene.render();
|
||||
scene.wait_for_render();
|
||||
EXPECT_EQ(order, (std::vector<int>{1, 2, 11, 12}));
|
||||
}
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
struct Renderable_Task_Graph_Concurrency_Test_Renderable : Renderable_Base {
|
||||
Renderable_Task_Graph_Concurrency_Test_Renderable(Scene_Base& scene, std::atomic<int>& active, std::atomic<int>& maximum)
|
||||
: Renderable_Base(scene, {.cache_enabled = false}), active(&active), maximum(&maximum) {}
|
||||
void build_task_graph(Renderable_Task_Graph& graph) override {
|
||||
auto work = [this](const Scene_Render_Context&) {
|
||||
const int value = active->fetch_add(1, std::memory_order_acq_rel) + 1;
|
||||
int observed = maximum->load(std::memory_order_acquire);
|
||||
while (observed < value && !maximum->compare_exchange_weak(observed, value, std::memory_order_acq_rel)) {}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
active->fetch_sub(1, std::memory_order_acq_rel);
|
||||
};
|
||||
graph.emplace(work, "parallel_a");
|
||||
graph.emplace(work, "parallel_b");
|
||||
}
|
||||
std::atomic<int>* active;
|
||||
std::atomic<int>* maximum;
|
||||
};
|
||||
TEST(renderable_task_graph_concurrency_test, DISABLED_runs_independent_internal_tasks_concurrently) {
|
||||
Scene2D_Context<> scene;
|
||||
std::atomic<int> active{};
|
||||
std::atomic<int> maximum{};
|
||||
auto renderable = std::make_shared<Renderable_Task_Graph_Concurrency_Test_Renderable>(scene, active, maximum);
|
||||
scene.attach_renderable(renderable);
|
||||
scene.render();
|
||||
scene.wait_for_render();
|
||||
EXPECT_GE(maximum.load(std::memory_order_acquire), 2);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
#include "renderive/renderable/Renderable.hpp"
|
||||
#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 {
|
||||
++render_count;
|
||||
}
|
||||
int render_count{};
|
||||
};
|
||||
TEST(renderable_base_test, exposes_scene_and_strategy_members_directly) {
|
||||
Scene2D_Context<> low_latency_scene;
|
||||
Scene2D_Context<Manual_Refresh_Strategy<Scene2D_Frame_Data>> manual_scene;
|
||||
Renderable_Base_Test_Renderable low_latency_renderable(low_latency_scene, true);
|
||||
Renderable_Base_Test_Renderable manual_renderable(manual_scene, true);
|
||||
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()));
|
||||
}
|
||||
TEST(renderable_base_test, controls_cache_with_configuration) {
|
||||
Scene2D_Context<> scene;
|
||||
auto cached = std::make_shared<Renderable_Base_Test_Renderable>(scene, true);
|
||||
auto uncached = std::make_shared<Renderable_Base_Test_Renderable>(scene, false);
|
||||
scene.attach_renderable(cached);
|
||||
scene.attach_renderable(uncached);
|
||||
scene.render();
|
||||
scene.wait_for_render();
|
||||
scene.render();
|
||||
scene.wait_for_render();
|
||||
EXPECT_EQ(cached->render_count, 1);
|
||||
EXPECT_EQ(uncached->render_count, 2);
|
||||
cached->invalidate_cache();
|
||||
scene.render();
|
||||
scene.wait_for_render();
|
||||
EXPECT_EQ(cached->render_count, 2);
|
||||
EXPECT_EQ(uncached->render_count, 3);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "renderive/renderable/Renderable.hpp"
|
||||
static_assert(Color_Cache_Type<Recording_Color_Cache>);
|
||||
TEST(color_cache_test, composites_source_values_in_order) {
|
||||
Recording_Color_Cache first;
|
||||
Recording_Color_Cache second;
|
||||
Recording_Color_Cache result;
|
||||
first.append(1);
|
||||
second.append(2);
|
||||
result.composite(first);
|
||||
result.composite(second);
|
||||
EXPECT_EQ(result.values, (std::vector<std::uint64_t>{1, 2}));
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <type_traits>
|
||||
#include "renderive/renderable/Renderable.hpp"
|
||||
#include "renderive/scene/Scene.hpp"
|
||||
struct Renderable_Concept_Test : Renderable_Base {
|
||||
explicit Renderable_Concept_Test(Scene_Base& scene) : Renderable_Base(scene) {}
|
||||
void render(const Scene_Render_Context&) override {}
|
||||
};
|
||||
static_assert(Renderable<Renderable_Concept_Test>);
|
||||
static_assert(!std::same_as<Renderable_Base::Layer_Node, Renderable_Base::Dependency_Node>);
|
||||
TEST(renderable_concept_test, exposes_tree_nodes_scene_and_configuration) {
|
||||
Scene2D_Context<> scene;
|
||||
Renderable_Concept_Test renderable(scene);
|
||||
EXPECT_EQ(renderable.scene, &scene);
|
||||
EXPECT_EQ(renderable.layer_node.owner, &renderable);
|
||||
EXPECT_EQ(renderable.dependency_node.owner, &renderable);
|
||||
EXPECT_FALSE(renderable.configuration.cache_enabled);
|
||||
}
|
||||
Reference in New Issue
Block a user