#include #include #include #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& 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* order; int base; }; TEST(renderable_task_graph_test, combines_internal_and_external_dependencies) { Scene2D_Context<> scene; std::vector order; auto dependency = std::make_shared(scene, order, 0); auto dependent = std::make_shared(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{1, 2, 11, 12})); } #include #include #include #include struct Renderable_Task_Graph_Concurrency_Test_Renderable : Renderable_Base { Renderable_Task_Graph_Concurrency_Test_Renderable(Scene_Base& scene, std::atomic& active, std::atomic& 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* active; std::atomic* maximum; }; TEST(renderable_task_graph_concurrency_test, DISABLED_runs_independent_internal_tasks_concurrently) { Scene2D_Context<> scene; std::atomic active{}; std::atomic maximum{}; auto renderable = std::make_shared(scene, active, maximum); scene.attach_renderable(renderable); scene.render(); scene.wait_for_render(); EXPECT_GE(maximum.load(std::memory_order_acquire), 2); }