Files
Renderive/Kernel/tests/renderive/scene/Scene_Memory_Resource_Test.cpp
T
2026-08-04 18:14:38 +08:00

99 lines
4.4 KiB
C++

#include <gtest/gtest.h>
#include <atomic>
#include <cstddef>
#include <memory>
#include <memory_resource>
#include <vector>
#include "renderive/base/property/Property.hpp"
#include "renderive/real_time_data/Real_Time_Data.hpp"
#include "renderive/renderable/Renderable.hpp"
#include "renderive/scene/Scene.hpp"
class Scene_Memory_Resource_Test_Resource : public std::pmr::memory_resource {
public:
std::size_t allocation_count() const noexcept {
return allocation_count_.load(std::memory_order_acquire);
}
std::size_t deallocation_count() const noexcept {
return deallocation_count_.load(std::memory_order_acquire);
}
private:
void* do_allocate(std::size_t bytes, std::size_t alignment) override {
allocation_count_.fetch_add(1, std::memory_order_release);
return std::pmr::new_delete_resource()->allocate(bytes, alignment);
}
void do_deallocate(void* pointer, std::size_t bytes, std::size_t alignment) override {
deallocation_count_.fetch_add(1, std::memory_order_release);
std::pmr::new_delete_resource()->deallocate(pointer, bytes, alignment);
}
bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override {
return this == &other;
}
std::atomic<std::size_t> allocation_count_{};
std::atomic<std::size_t> deallocation_count_{};
};
struct Scene_Memory_Resource_Test_Renderable : Renderable_Base {
explicit Scene_Memory_Resource_Test_Renderable(Scene_Base& scene) : Renderable_Base(scene, {.cache_enabled = false}) {}
void build_task_graph(Renderable_Task_Graph& graph) override {
auto first = graph.emplace([](const Scene_Render_Context&) {}, "prepare_memory_resource_test");
auto second = graph.emplace([](const Scene_Render_Context&) {}, "render_memory_resource_test");
graph.precede(first, second);
}
};
struct Scene_Memory_Resource_Test_Product {
explicit Scene_Memory_Resource_Test_Product(int value) : value(value) {}
int value;
};
struct Scene_Memory_Resource_Test_Properties {
int value{};
};
struct Scene_Memory_Resource_Test_Property_Product {
Scene_Memory_Resource_Test_Property_Product(const Scene_Memory_Resource_Test_Properties& properties, int offset) : value(properties.value + offset) {}
int value;
};
TEST(scene_memory_resource_test, propagates_thread_safe_scene_memory_domain) {
Scene_Memory_Resource_Test_Resource upstream;
Scene2D_Context<> scene(upstream);
EXPECT_EQ(&scene.upstream_memory_resource(), &upstream);
EXPECT_NE(&scene.memory_resource(), &upstream);
auto factory_renderable = scene.make_renderable<Scene_Memory_Resource_Test_Renderable>();
auto independent_renderable = std::make_shared<Scene_Memory_Resource_Test_Renderable>(scene);
EXPECT_EQ(&factory_renderable->memory_resource(), &scene.memory_resource());
EXPECT_EQ(&independent_renderable->memory_resource(), &scene.memory_resource());
scene.attach_renderable(factory_renderable);
scene.attach_renderable(independent_renderable);
scene.render();
scene.wait_for_render();
EXPECT_GT(upstream.allocation_count(), 0);
}
TEST(scene_memory_resource_test, keeps_factory_memory_domain_alive_until_renderable_release) {
Scene_Memory_Resource_Test_Resource upstream;
std::shared_ptr<Scene_Memory_Resource_Test_Renderable> renderable;
{
Scene2D_Context<> scene(upstream);
renderable = scene.make_renderable<Scene_Memory_Resource_Test_Renderable>();
renderable->task_graph();
}
renderable.reset();
EXPECT_GT(upstream.deallocation_count(), 0);
}
TEST(scene_memory_resource_test, supports_independent_resource_aware_components) {
Scene_Memory_Resource_Test_Resource memory_resource;
Flow_Refresh_Strategy<Scene2D_Frame_Data> flow(memory_resource);
{
auto painter = flow.acquire_painter();
EXPECT_TRUE(painter);
}
auto renderer = flow.acquire_renderer();
EXPECT_TRUE(renderer);
History_Real_Time_Data<int, std::pmr::vector<int>> history(memory_resource);
history.update(1);
history.update(2);
EXPECT_EQ(history.size(), 2);
Property_Builder<Scene_Memory_Resource_Test_Property_Product, Scene_Memory_Resource_Test_Properties> builder({3});
auto product = builder.build_with_resource(memory_resource, 4);
auto unique_product = builder.build_unique_with_resource(memory_resource, 5);
EXPECT_EQ(product->value, 7);
EXPECT_EQ(unique_product->value, 8);
EXPECT_GT(memory_resource.allocation_count(), 0);
}