5 #include "fml/synchronization/waitable_event.h"
6 #include "gtest/gtest.h"
8 #include "impeller/renderer/backend/vulkan/test/mock_vulkan.h"
14 auto default_submit_callback = [](vk::Fence) {
return fml::Status(); };
17 TEST(FenceWaiterVKTest, IgnoresNullFence) {
18 auto const context = MockVulkanContextBuilder().Build();
19 auto const waiter =
context->GetFenceWaiter();
20 const auto add_status =
21 waiter->AddFence(vk::UniqueFence(), default_submit_callback, []() {});
22 EXPECT_EQ(add_status.code(), fml::StatusCode::kInvalidArgument);
25 TEST(FenceWaiterVKTest, IgnoresNullCallback) {
26 auto const context = MockVulkanContextBuilder().Build();
27 auto const device =
context->GetDevice();
28 auto const waiter =
context->GetFenceWaiter();
30 auto fence = device.createFenceUnique({}).
value;
31 const auto add_status =
32 waiter->AddFence(std::move(fence), default_submit_callback,
nullptr);
33 EXPECT_EQ(add_status.code(), fml::StatusCode::kInvalidArgument);
36 TEST(FenceWaiterVKTest, ReturnsSubmitError) {
37 auto const context = MockVulkanContextBuilder().Build();
38 auto const device =
context->GetDevice();
39 auto const waiter =
context->GetFenceWaiter();
41 auto submit_callback = [&](vk::Fence) {
42 return fml::Status(fml::StatusCode::kCancelled,
"Submit failed");
45 auto fence = device.createFenceUnique({}).
value;
46 const auto add_status =
47 waiter->AddFence(std::move(fence), submit_callback, []() {});
48 EXPECT_EQ(add_status.code(), fml::StatusCode::kCancelled);
51 TEST(FenceWaiterVKTest, ExecutesFenceCallback) {
52 auto const context = MockVulkanContextBuilder().Build();
53 auto const device =
context->GetDevice();
54 auto const waiter =
context->GetFenceWaiter();
56 bool submit_called =
false;
57 auto submit_callback = [&](vk::Fence) {
62 auto signal = fml::ManualResetWaitableEvent();
63 auto fence = device.createFenceUnique({}).
value;
64 waiter->AddFence(std::move(fence), submit_callback,
65 [&signal]() { signal.Signal(); });
66 EXPECT_TRUE(submit_called);
71 TEST(FenceWaiterVKTest, ExecutesFenceCallbackX2) {
72 auto const context = MockVulkanContextBuilder().Build();
73 auto const device =
context->GetDevice();
74 auto const waiter =
context->GetFenceWaiter();
76 auto signal = fml::ManualResetWaitableEvent();
77 auto fence = device.createFenceUnique({}).
value;
78 waiter->AddFence(std::move(fence), default_submit_callback,
79 [&signal]() { signal.Signal(); });
81 auto signal2 = fml::ManualResetWaitableEvent();
82 auto fence2 = device.createFenceUnique({}).
value;
83 waiter->AddFence(std::move(fence2), default_submit_callback,
84 [&signal2]() { signal2.Signal(); });
90 TEST(FenceWaiterVKTest, ExecutesNewFenceThenOldFence) {
91 auto const context = MockVulkanContextBuilder().Build();
92 auto const device =
context->GetDevice();
93 auto const waiter =
context->GetFenceWaiter();
95 auto signal = fml::ManualResetWaitableEvent();
96 auto fence = device.createFenceUnique({}).
value;
97 MockFence::SetStatus(fence, vk::Result::eNotReady);
98 auto raw_fence = MockFence::GetRawPointer(fence);
99 waiter->AddFence(std::move(fence), default_submit_callback,
100 [&signal]() { signal.Signal(); });
106 auto signal2 = fml::ManualResetWaitableEvent();
107 auto fence2 = device.createFenceUnique({}).
value;
108 MockFence::SetStatus(fence2, vk::Result::eSuccess);
109 waiter->AddFence(std::move(fence2), default_submit_callback,
110 [&signal2]() { signal2.Signal(); });
115 raw_fence->SetStatus(vk::Result::eSuccess);
121 TEST(FenceWaiterVKTest, AddFenceDoesNothingIfTerminating) {
122 auto signal = fml::ManualResetWaitableEvent();
125 auto const context = MockVulkanContextBuilder().Build();
126 auto const device =
context->GetDevice();
127 auto const waiter =
context->GetFenceWaiter();
130 auto fence = device.createFenceUnique({}).
value;
131 waiter->AddFence(std::move(fence), default_submit_callback,
132 [&signal]() { signal.Signal(); });
136 EXPECT_TRUE(signal.WaitWithTimeout(fml::TimeDelta::FromMilliseconds(100)));
139 TEST(FenceWaiterVKTest, InProgressFencesStillWaitIfTerminated) {
140 MockFence* raw_fence =
nullptr;
141 auto signal = fml::ManualResetWaitableEvent();
143 auto const context = MockVulkanContextBuilder().Build();
144 auto const device =
context->GetDevice();
145 auto const waiter =
context->GetFenceWaiter();
148 auto fence = device.createFenceUnique({}).
value;
151 MockFence::SetStatus(fence, vk::Result::eNotReady);
152 raw_fence = MockFence::GetRawPointer(fence);
153 waiter->AddFence(std::move(fence), default_submit_callback,
154 [&signal]() { signal.Signal(); });
157 std::thread thread([&]() {
158 std::this_thread::sleep_for(std::chrono::milliseconds{100u});
159 raw_fence->SetStatus(vk::Result::eSuccess);
TEST(AllocationSizeTest, CanCreateTypedAllocations)
std::shared_ptr< ContextGLES > context