15 #include "flutter/third_party/abseil-cpp/absl/base/no_destructor.h"
16 #include "fml/closure.h"
22 #define GLFW_INCLUDE_NONE
23 #include "third_party/glfw/include/GLFW/glfw3.h"
28 std::unique_ptr<PlaygroundImpl> MakeVulkanPlayground(
bool enable_validations) {
29 FML_CHECK(::glfwInit() == GLFW_TRUE);
30 PlaygroundSwitches playground_switches;
31 playground_switches.enable_vulkan_validation = enable_validations;
37 const std::unique_ptr<PlaygroundImpl>& GetSharedVulkanPlayground(
38 bool enable_validations) {
39 if (enable_validations) {
40 static absl::NoDestructor<std::unique_ptr<PlaygroundImpl>>
41 vulkan_validation_playground(
42 MakeVulkanPlayground(
true));
45 static fml::ScopedCleanupClosure context_cleanup(
46 [&] { (*vulkan_validation_playground)->GetContext()->Shutdown(); });
47 return *vulkan_validation_playground;
49 static absl::NoDestructor<std::unique_ptr<PlaygroundImpl>>
50 vulkan_playground(MakeVulkanPlayground(
false));
53 static fml::ScopedCleanupClosure context_cleanup(
54 [&] { (*vulkan_playground)->GetContext()->Shutdown(); });
55 return *vulkan_playground;
60 #define IMP_AIKSTEST(name) \
61 "impeller_Play_AiksTest_" #name "_Metal", \
62 "impeller_Play_AiksTest_" #name "_OpenGLES", \
63 "impeller_Play_AiksTest_" #name "_Vulkan"
72 "impeller_Play_AiksTest_CanRenderClippedRuntimeEffects_Vulkan",
76 std::string GetTestName() {
77 std::string suite_name =
78 ::testing::UnitTest::GetInstance()->current_test_suite()->name();
79 std::string test_name =
80 ::testing::UnitTest::GetInstance()->current_test_info()->name();
82 ss <<
"impeller_" << suite_name <<
"_" << test_name;
83 std::string result = ss.str();
85 std::replace(result.begin(), result.end(),
'/',
'_');
89 std::string GetGoldenFilename() {
90 return GetTestName() +
".png";
93 bool SaveScreenshot(std::unique_ptr<testing::Screenshot> screenshot) {
94 if (!screenshot || !screenshot->GetBytes()) {
95 FML_LOG(ERROR) <<
"Failed to collect screenshot for test " << GetTestName();
98 std::string test_name = GetTestName();
99 std::string filename = GetGoldenFilename();
101 test_name, filename, screenshot->GetWidth(), screenshot->GetHeight());
102 if (!screenshot->WriteToPNG(
104 FML_LOG(ERROR) <<
"Failed to write screenshot to " << filename;
126 std::shared_ptr<TypographerContext> typographer_context) {
127 typographer_context_ = std::move(typographer_context);
131 ASSERT_FALSE(dlopen(
"/usr/local/lib/libMoltenVK.dylib", RTLD_NOLOAD));
135 bool DoesSupportWideGamutTests() {
145 std::filesystem::path testing_assets_path =
146 flutter::testing::GetTestingAssetsPath();
147 std::filesystem::path target_path = testing_assets_path.parent_path()
151 std::filesystem::path icd_path = target_path /
"vk_swiftshader_icd.json";
152 setenv(
"VK_ICD_FILENAMES", icd_path.c_str(), 1);
154 std::string test_name = GetTestName();
155 bool enable_wide_gamut = test_name.find(
"WideGamut_") != std::string::npos;
156 switch (GetParam()) {
158 if (!DoesSupportWideGamutTests()) {
160 "This metal device doesn't support wide gamut golden tests.");
162 pimpl_->screenshotter =
163 std::make_unique<testing::MetalScreenshotter>(enable_wide_gamut);
166 if (enable_wide_gamut) {
167 GTEST_SKIP_(
"Vulkan doesn't support wide gamut golden tests.");
169 const std::unique_ptr<PlaygroundImpl>& playground =
170 GetSharedVulkanPlayground(
true);
171 pimpl_->screenshotter =
172 std::make_unique<testing::VulkanScreenshotter>(playground);
176 if (enable_wide_gamut) {
177 GTEST_SKIP_(
"OpenGLES doesn't support wide gamut golden tests.");
179 FML_CHECK(::glfwInit() == GLFW_TRUE);
184 pimpl_->screenshotter = std::make_unique<testing::VulkanScreenshotter>(
185 pimpl_->test_opengl_playground);
193 "GoldenPlaygroundTest doesn't support interactive playground tests "
198 "gpu_string",
GetContext()->DescribeGpuModel());
208 auto screenshot = pimpl_->screenshotter->MakeScreenshot(renderer, picture,
209 pimpl_->window_size);
210 return SaveScreenshot(std::move(screenshot));
217 std::optional<Picture> picture;
218 std::unique_ptr<testing::Screenshot> screenshot;
219 for (
int i = 0; i < 2; ++i) {
220 auto display_list = callback();
222 display_list->Dispatch(dispatcher);
225 screenshot = pimpl_->screenshotter->MakeScreenshot(renderer, picture,
226 pimpl_->window_size);
229 return SaveScreenshot(std::move(screenshot));
237 std::optional<Picture> picture;
238 std::unique_ptr<testing::Screenshot> screenshot;
239 for (
int i = 0; i < 2; ++i) {
240 picture = callback(renderer);
241 if (!picture.has_value()) {
244 screenshot = pimpl_->screenshotter->MakeScreenshot(
245 renderer, picture.value(), pimpl_->window_size);
248 return SaveScreenshot(std::move(screenshot));
252 const sk_sp<flutter::DisplayList>& list) {
254 list->Dispatch(dispatcher);
261 ImGuiWindowFlags flags) {
266 const char* fixture_name,
267 bool enable_mipmapping)
const {
268 std::shared_ptr<fml::Mapping> mapping =
269 flutter::testing::OpenFixtureAsMapping(fixture_name);
273 result->SetLabel(fixture_name);
279 const char* fixture_name,
280 bool enable_mipmapping)
const {
281 std::shared_ptr<Texture> texture =
287 const char* asset_name)
const {
288 const std::shared_ptr<fml::Mapping> fixture =
289 flutter::testing::OpenFixtureAsMapping(asset_name);
290 if (!fixture || fixture->GetSize() == 0) {
297 return pimpl_->screenshotter->GetPlayground().GetContext();
305 bool enable_vulkan_validations =
true;
306 FML_CHECK(!pimpl_->test_vulkan_playground)
307 <<
"We don't support creating multiple contexts for one test";
308 pimpl_->test_vulkan_playground =
309 MakeVulkanPlayground(enable_vulkan_validations);
310 pimpl_->screenshotter = std::make_unique<testing::VulkanScreenshotter>(
311 pimpl_->test_vulkan_playground);
312 return pimpl_->test_vulkan_playground->GetContext();
320 return pimpl_->screenshotter->GetPlayground().GetContentScale();
328 return pimpl_->window_size;
331 void GoldenPlaygroundTest::GoldenPlaygroundTest::SetWindowSize(
ISize size) {
332 pimpl_->window_size = size;
336 const std::shared_ptr<Capabilities>& capabilities) {
337 return pimpl_->screenshotter->GetPlayground().SetCapabilities(capabilities);