3D 优化
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
#include <render_3D/Render_3D.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
namespace aethera::render_3d {
|
||||
namespace {
|
||||
template <typename Visual, typename Item>
|
||||
@@ -46,59 +43,37 @@ TEST(Render_3D_Scene, Builder_Instantiates_Async_Paint_Contract) {
|
||||
scene_builder.add_renderable(visual.get()).add_camera(camera.get()).add_axes(axes.get());
|
||||
static_assert(std::same_as<decltype(scene_builder.build()), std::expected<std::unique_ptr<Scene_Object>, Dependency_Graph_Error>>);
|
||||
}
|
||||
TEST(Render_3D_Scene, Paint_Submits_Without_Waiting_For_Gpu) {
|
||||
using Visual_Object = Point_Visual;
|
||||
using Scene_Object = Render_Scene_3D;
|
||||
auto visual_result = typename Visual_Object::template Builder<Visual_Object>{}.build();
|
||||
ASSERT_TRUE(visual_result.has_value());
|
||||
auto visual = std::move(visual_result).value();
|
||||
auto camera = *Camera_3D::Builder<Camera_3D>{}.build();
|
||||
auto axes = *Axes_3D::Builder<Axes_3D>{}.build();
|
||||
visual->set<&Point_Visual::Prop::items>(std::vector<Point>{Point{.position = {0.0F, 0.0F, 0.0F}, .color = Color::red_color(), .diameter_px = 8.0F}});
|
||||
visual->advance();
|
||||
try {
|
||||
typename Scene_Object::template Builder<Scene_Object> scene_builder;
|
||||
scene_builder.add_renderable(visual.get()).add_camera(camera.get()).add_axes(axes.get());
|
||||
auto scene_result = scene_builder.build();
|
||||
ASSERT_TRUE(scene_result.has_value());
|
||||
auto scene = std::move(scene_result).value();
|
||||
std::atomic_bool frame_ready{};
|
||||
Frame_3D frame{Frame_Identity{1, 0}};
|
||||
Frame_3D unchanged_frame{Frame_Identity{2, 0}};
|
||||
Frame_3D exchanged_unchanged_frame{Frame_Identity{3, 0}};
|
||||
Frame_3D* completed_frame{};
|
||||
std::atomic_size_t completion_calls{};
|
||||
scene->completion_taskflow().add("test.scene_3d.completion", [&] {
|
||||
completion_calls.fetch_add(1, std::memory_order_release);
|
||||
});
|
||||
scene->set_frame_callback([&](Frame_3D* value) {
|
||||
EXPECT_GT(completion_calls.load(std::memory_order_acquire), 0u);
|
||||
completed_frame = value;
|
||||
frame_ready.store(true, std::memory_order_release);
|
||||
});
|
||||
const auto started = std::chrono::steady_clock::now();
|
||||
EXPECT_EQ(scene->render(&frame), Render_Scene_3D::Render_Result::submitted);
|
||||
const auto submit_duration = std::chrono::steady_clock::now() - started;
|
||||
EXPECT_LT(submit_duration, std::chrono::seconds(1));
|
||||
for (std::size_t attempt = 0; attempt != 500 && !frame_ready.load(std::memory_order_acquire); ++attempt) std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
EXPECT_EQ(completed_frame, &frame);
|
||||
EXPECT_FALSE(frame.pixels().empty());
|
||||
frame_ready.store(false, std::memory_order_release);
|
||||
completed_frame = nullptr;
|
||||
EXPECT_EQ(scene->render(&unchanged_frame), Render_Scene_3D::Render_Result::submitted);
|
||||
for (std::size_t attempt = 0; attempt != 500 && !frame_ready.load(std::memory_order_acquire); ++attempt) std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
EXPECT_EQ(completed_frame, &unchanged_frame);
|
||||
EXPECT_FALSE(unchanged_frame.pixels().empty());
|
||||
frame_ready.store(false, std::memory_order_release);
|
||||
completed_frame = nullptr;
|
||||
EXPECT_EQ(scene->render(&exchanged_unchanged_frame), Render_Scene_3D::Render_Result::submitted);
|
||||
for (std::size_t attempt = 0; attempt != 500 && !frame_ready.load(std::memory_order_acquire); ++attempt) std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
EXPECT_EQ(completed_frame, &exchanged_unchanged_frame);
|
||||
EXPECT_EQ(completion_calls.load(std::memory_order_acquire), 3u);
|
||||
EXPECT_TRUE(std::ranges::equal(unchanged_frame.pixels(), exchanged_unchanged_frame.pixels()));
|
||||
}
|
||||
catch (const std::exception& error) {
|
||||
GTEST_SKIP() << "Vulkan/Datoviz unavailable: " << error.what();
|
||||
}
|
||||
TEST(Render_3D_Visual, Prepared_Data_Preserves_Datoviz_Attributes) {
|
||||
detail::Mesh_Prepared_Data mesh;
|
||||
detail::Mesh_Spec::prepare(
|
||||
std::vector<Mesh_Vertex>{{.texture_coordinate = {0.25F, 0.75F}}},
|
||||
mesh);
|
||||
ASSERT_EQ(mesh.texture_coordinates.size(), 1U);
|
||||
EXPECT_EQ(mesh.texture_coordinates.front(),
|
||||
(std::array<float, 2>{0.25F, 0.75F}));
|
||||
|
||||
detail::Image_Prepared_Data image;
|
||||
detail::Image_Spec::prepare(
|
||||
std::vector<Image>{{.texture_rectangle = {0.1F, 0.2F, 0.8F, 0.9F}}},
|
||||
image);
|
||||
EXPECT_EQ(image.texture_rectangles.front(),
|
||||
(std::array<float, 4>{0.1F, 0.2F, 0.8F, 0.9F}));
|
||||
|
||||
detail::Glyph_Prepared_Data glyph;
|
||||
detail::Glyph_Spec::prepare(std::vector<Glyph>{{
|
||||
.bounds = {-1.0F, -2.0F, 3.0F, 4.0F},
|
||||
.texture_coordinates = {0.0F, 0.1F, 0.9F, 1.0F},
|
||||
.angle = 0.5F}}, glyph);
|
||||
EXPECT_EQ(glyph.bounds.front(),
|
||||
(std::array<float, 4>{-1.0F, -2.0F, 3.0F, 4.0F}));
|
||||
EXPECT_EQ(glyph.texture_coordinates.front(),
|
||||
(std::array<float, 4>{0.0F, 0.1F, 0.9F, 1.0F}));
|
||||
|
||||
detail::Text_Prepared_Data text;
|
||||
detail::Text_Spec::prepare(
|
||||
std::vector<Text_Label>{{.text = "dynamic", .size_px = 23.0F}}, text);
|
||||
ASSERT_EQ(text.strings.size(), 1U);
|
||||
EXPECT_EQ(text.strings.front(), "dynamic");
|
||||
EXPECT_FLOAT_EQ(text.sizes.front(), 23.0F);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user