Flutter Engine
The Flutter Engine
embedder_vk_unittests.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#define FML_USED_ON_EMBEDDER
6
7#include <cstring>
8#include <string>
9#include <utility>
10#include <vector>
11
12#include "embedder.h"
13#include "embedder_engine.h"
14#include "flutter/fml/synchronization/count_down_latch.h"
15#include "flutter/shell/platform/embedder/tests/embedder_config_builder.h"
16#include "flutter/shell/platform/embedder/tests/embedder_test.h"
17#include "flutter/shell/platform/embedder/tests/embedder_test_context_vulkan.h"
18#include "flutter/shell/platform/embedder/tests/embedder_unittests_util.h"
19#include "flutter/testing/testing.h"
20
21// CREATE_NATIVE_ENTRY is leaky by design
22// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape)
23
24namespace flutter {
25namespace testing {
26
28
29////////////////////////////////////////////////////////////////////////////////
30// Notice: Other Vulkan unit tests exist in embedder_gl_unittests.cc.
31// See https://github.com/flutter/flutter/issues/134322
32////////////////////////////////////////////////////////////////////////////////
33
34namespace {
35
36struct VulkanProcInfo {
41};
42
43static_assert(std::is_trivially_destructible_v<VulkanProcInfo>);
44
45VulkanProcInfo g_vulkan_proc_info;
46
47VkResult QueueSubmit(VkQueue queue,
48 uint32_t submitCount,
49 const VkSubmitInfo* pSubmits,
50 VkFence fence) {
51 FML_DCHECK(g_vulkan_proc_info.queue_submit_proc_addr != nullptr);
52 g_vulkan_proc_info.did_call_queue_submit = true;
53 return g_vulkan_proc_info.queue_submit_proc_addr(queue, submitCount, pSubmits,
54 fence);
55}
56
57template <size_t N>
58int StrcmpFixed(const char* str1, const char (&str2)[N]) {
59 return strncmp(str1, str2, N - 1);
60}
61
62PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
63 FML_DCHECK(g_vulkan_proc_info.get_device_proc_addr != nullptr);
64 if (StrcmpFixed(pName, "vkQueueSubmit") == 0) {
65 g_vulkan_proc_info.queue_submit_proc_addr =
66 reinterpret_cast<decltype(vkQueueSubmit)*>(
67 g_vulkan_proc_info.get_device_proc_addr(device, pName));
68 return reinterpret_cast<PFN_vkVoidFunction>(QueueSubmit);
69 }
70 return g_vulkan_proc_info.get_device_proc_addr(device, pName);
71}
72
73PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
74 FML_DCHECK(g_vulkan_proc_info.get_instance_proc_addr != nullptr);
75 if (StrcmpFixed(pName, "vkGetDeviceProcAddr") == 0) {
76 g_vulkan_proc_info.get_device_proc_addr =
77 reinterpret_cast<decltype(vkGetDeviceProcAddr)*>(
78 g_vulkan_proc_info.get_instance_proc_addr(instance, pName));
79 return reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr);
80 }
81 return g_vulkan_proc_info.get_instance_proc_addr(instance, pName);
82}
83
84template <typename T, typename U>
85struct CheckSameSignature : std::false_type {};
86
87template <typename Ret, typename... Args>
88struct CheckSameSignature<Ret(Args...), Ret(Args...)> : std::true_type {};
89
90static_assert(CheckSameSignature<decltype(GetInstanceProcAddr),
92static_assert(CheckSameSignature<decltype(GetDeviceProcAddr),
94static_assert(
95 CheckSameSignature<decltype(QueueSubmit), decltype(vkQueueSubmit)>::value);
96} // namespace
97
98TEST_F(EmbedderTest, CanSwapOutVulkanCalls) {
99 auto& context = GetEmbedderContext(EmbedderTestContextType::kVulkanContext);
101 context.AddIsolateCreateCallback([&latch]() { latch.Signal(); });
103 builder.SetVulkanRendererConfig(
104 SkISize::Make(1024, 1024),
106 const char* name) -> void* {
107 if (StrcmpFixed(name, "vkGetInstanceProcAddr") == 0) {
108 g_vulkan_proc_info.get_instance_proc_addr =
109 reinterpret_cast<decltype(vkGetInstanceProcAddr)*>(
111 instance, name));
112 return reinterpret_cast<void*>(GetInstanceProcAddr);
113 }
115 name);
116 });
117 auto engine = builder.LaunchEngine();
118 ASSERT_TRUE(engine.is_valid());
119 // Wait for the root isolate to launch.
120 latch.Wait();
121 engine.reset();
122 EXPECT_TRUE(g_vulkan_proc_info.did_call_queue_submit);
123}
124
125} // namespace testing
126} // namespace flutter
127
128// NOLINTEND(clang-analyzer-core.StackAddressEscape)
#define N
Definition: beziers.cpp:19
static void * InstanceProcAddr(void *user_data, FlutterVulkanInstanceHandle instance, const char *name)
void * FlutterVulkanInstanceHandle
Alias for VkInstance.
Definition: embedder.h:708
decltype(vkGetInstanceProcAddr) * get_instance_proc_addr
bool did_call_queue_submit
decltype(vkGetDeviceProcAddr) * get_device_proc_addr
decltype(vkQueueSubmit) * queue_submit_proc_addr
VkDevice device
Definition: main.cc:53
FlutterEngine engine
Definition: main.cc:68
VkInstance instance
Definition: main.cc:48
VkQueue queue
Definition: main.cc:55
uint8_t value
#define FML_DCHECK(condition)
Definition: logging.h:103
TEST_F(DisplayListTest, Defaults)
testing::EmbedderTest EmbedderTest
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
void * user_data
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *pName)
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char *pName)
VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence)
VkResult
Definition: vulkan_core.h:140
void(VKAPI_PTR * PFN_vkVoidFunction)(void)
Definition: vulkan_core.h:2992