68 {
69
70
72
73 "impeller_Play_AiksTest_CanRenderClippedRuntimeEffects_Vulkan",
74};
75
76namespace {
77std::string GetTestName() {
78 std::string suite_name =
79 ::testing::UnitTest::GetInstance()->current_test_suite()->name();
80 std::string test_name =
81 ::testing::UnitTest::GetInstance()->current_test_info()->name();
82 std::stringstream ss;
83 ss << "impeller_" << suite_name << "_" << test_name;
84 std::string result = ss.str();
85
86 std::replace(result.begin(), result.end(), '/', '_');
87 return result;
88}
89
90std::string GetGoldenFilename(const std::string& postfix) {
91 return GetTestName() + postfix + ".png";
92}
93}
94
95bool GoldenPlaygroundTest::SaveScreenshot(
96 std::unique_ptr<testing::Screenshot> screenshot,
97 const std::string& postfix) {
98 if (!screenshot || !screenshot->GetBytes()) {
99 FML_LOG(ERROR) <<
"Failed to collect screenshot for test " << GetTestName();
100 return false;
101 }
102 std::string test_name = GetTestName();
103 std::string filename = GetGoldenFilename(postfix);
104 testing::GoldenDigest::Instance()->AddImage(
105 test_name, filename, screenshot->GetWidth(), screenshot->GetHeight());
106 if (!screenshot->WriteToPNG(
107 testing::WorkingDirectory::Instance()->GetFilenamePath(filename))) {
108 FML_LOG(ERROR) <<
"Failed to write screenshot to " << filename;
109 return false;
110 }
111 return true;
112}
113
114struct GoldenPlaygroundTest::GoldenPlaygroundTestImpl {
115 std::unique_ptr<PlaygroundImpl> test_vulkan_playground;
116 std::unique_ptr<PlaygroundImpl> test_opengl_playground;
117 std::unique_ptr<testing::Screenshotter> screenshotter;
119};
120
121GoldenPlaygroundTest::GoldenPlaygroundTest()
122 : typographer_context_(TypographerContextSkia::Make()),
123 pimpl_(new GoldenPlaygroundTest::GoldenPlaygroundTestImpl()) {}
124
125GoldenPlaygroundTest::~GoldenPlaygroundTest() = default;
126
127void GoldenPlaygroundTest::SetTypographerContext(
128 std::shared_ptr<TypographerContext> typographer_context) {
129 typographer_context_ = std::move(typographer_context);
130};
131
132void GoldenPlaygroundTest::TearDown() {
133 ASSERT_FALSE(dlopen("/usr/local/lib/libMoltenVK.dylib", RTLD_NOLOAD));
134
135 auto context = GetContext();
136 if (context) {
137 context->DisposeThreadLocalCachedResources();
138 }
139}
140
141namespace {
142bool DoesSupportWideGamutTests() {
143#ifdef __arm64__
144 return true;
145#else
146 return false;
147#endif
148}
149}
150
151void GoldenPlaygroundTest::SetUp() {
152 std::filesystem::path testing_assets_path =
154 std::filesystem::path target_path = testing_assets_path.parent_path()
155 .parent_path()
156 .parent_path()
157 .parent_path();
158 std::filesystem::path icd_path = target_path / "vk_swiftshader_icd.json";
159 setenv("VK_ICD_FILENAMES", icd_path.c_str(), 1);
160
161 std::string test_name = GetTestName();
162 PlaygroundSwitches switches;
163 switches.enable_wide_gamut =
164 test_name.find("WideGamut_") != std::string::npos;
165 switches.flags.antialiased_lines =
166 test_name.find("ExperimentAntialiasLines_") != std::string::npos;
167 switch (GetParam()) {
168 case PlaygroundBackend::kMetal:
169 if (!DoesSupportWideGamutTests()) {
170 GTEST_SKIP()
171 << "This metal device doesn't support wide gamut golden tests.";
172 }
173 pimpl_->screenshotter =
174 std::make_unique<testing::MetalScreenshotter>(switches);
175 break;
176 case PlaygroundBackend::kVulkan: {
177 if (switches.enable_wide_gamut) {
178 GTEST_SKIP() << "Vulkan doesn't support wide gamut golden tests.";
179 }
180 if (switches.flags.antialiased_lines) {
181 GTEST_SKIP()
182 << "Vulkan doesn't support antialiased lines golden tests.";
183 }
184 const std::unique_ptr<PlaygroundImpl>& playground =
185 GetSharedVulkanPlayground(true);
186 pimpl_->screenshotter =
187 std::make_unique<testing::VulkanScreenshotter>(playground);
188 break;
189 }
190 case PlaygroundBackend::kOpenGLES: {
191 if (switches.enable_wide_gamut) {
192 GTEST_SKIP() << "OpenGLES doesn't support wide gamut golden tests.";
193 }
194 if (switches.flags.antialiased_lines) {
195 GTEST_SKIP()
196 << "OpenGLES doesn't support antialiased lines golden tests.";
197 }
199 PlaygroundSwitches playground_switches;
200 playground_switches.use_angle = true;
201 pimpl_->test_opengl_playground = PlaygroundImpl::Create(
202 PlaygroundBackend::kOpenGLES, playground_switches);
203 pimpl_->screenshotter = std::make_unique<testing::VulkanScreenshotter>(
204 pimpl_->test_opengl_playground);
205 break;
206 }
207 }
208
211 GTEST_SKIP()
212 << "GoldenPlaygroundTest doesn't support interactive playground tests "
213 "yet.";
214 }
215
216 testing::GoldenDigest::Instance()->AddDimension(
217 "gpu_string", GetContext()->DescribeGpuModel());
218}
219
221 return GetParam();
222}
223
224bool GoldenPlaygroundTest::OpenPlaygroundHere(
225 const AiksDlPlaygroundCallback&
callback) {
226 AiksContext renderer(GetContext(), typographer_context_);
227
228 std::unique_ptr<testing::Screenshot> screenshot;
229 Point content_scale =
230 pimpl_->screenshotter->GetPlayground().GetContentScale();
231
232 ISize physical_window_size(
233 std::round(pimpl_->window_size.width * content_scale.x),
234 std::round(pimpl_->window_size.height * content_scale.y));
235 for (
int i = 0;
i < 2; ++
i) {
239 screenshot = pimpl_->screenshotter->MakeScreenshot(renderer,
texture);
240 }
241 return SaveScreenshot(std::move(screenshot));
242}
243
244bool GoldenPlaygroundTest::OpenPlaygroundHere(
245 const sk_sp<flutter::DisplayList>& list) {
246 return OpenPlaygroundHere([&list]() { return list; });
247}
248
249bool GoldenPlaygroundTest::ImGuiBegin(
const char*
name,
250 bool* p_open,
251 ImGuiWindowFlags flags) {
252 return false;
253}
254
255std::shared_ptr<Texture> GoldenPlaygroundTest::CreateTextureForFixture(
256 const char* fixture_name,
257 bool enable_mipmapping) const {
258 std::shared_ptr<fml::Mapping> mapping =
260 auto result = Playground::CreateTextureForMapping(GetContext(), mapping,
261 enable_mipmapping);
262 if (result) {
263 result->SetLabel(fixture_name);
264 }
265 return result;
266}
267
268sk_sp<flutter::DlImage> GoldenPlaygroundTest::CreateDlImageForFixture(
269 const char* fixture_name,
270 bool enable_mipmapping) const {
271 std::shared_ptr<Texture>
texture =
272 CreateTextureForFixture(fixture_name, enable_mipmapping);
273 return DlImageImpeller::Make(
texture);
274}
275
276RuntimeStage::Map GoldenPlaygroundTest::OpenAssetAsRuntimeStage(
277 const char* asset_name) const {
278 const std::shared_ptr<fml::Mapping> fixture =
280 if (!fixture || fixture->GetSize() == 0) {
281 return {};
282 }
283 return RuntimeStage::DecodeRuntimeStages(fixture);
284}
285
286std::shared_ptr<Context> GoldenPlaygroundTest::GetContext() const {
287 if (!pimpl_->screenshotter) {
288 return nullptr;
289 }
290 return pimpl_->screenshotter->GetPlayground().GetContext();
291}
292
293std::shared_ptr<Context> GoldenPlaygroundTest::MakeContext() const {
294 if (GetParam() == PlaygroundBackend::kMetal) {
295
296 return GetContext();
297 } else if (GetParam() == PlaygroundBackend::kVulkan) {
298 bool enable_vulkan_validations = true;
299 FML_CHECK(!pimpl_->test_vulkan_playground)
300 << "We don't support creating multiple contexts for one test";
301 pimpl_->test_vulkan_playground =
302 MakeVulkanPlayground(enable_vulkan_validations);
303 pimpl_->screenshotter = std::make_unique<testing::VulkanScreenshotter>(
304 pimpl_->test_vulkan_playground);
305 return pimpl_->test_vulkan_playground->GetContext();
306 } else {
307
308 return GetContext();
309 }
310}
311
312Point GoldenPlaygroundTest::GetContentScale()
const {
313 return pimpl_->screenshotter->GetPlayground().GetContentScale();
314}
315
316Scalar GoldenPlaygroundTest::GetSecondsElapsed()
const {
317 return 0.0f;
318}
319
320ISize GoldenPlaygroundTest::GetWindowSize()
const {
321 return pimpl_->window_size;
322}
323
324void GoldenPlaygroundTest::GoldenPlaygroundTest::SetWindowSize(ISize size) {
325 pimpl_->window_size =
size;
326}
327
329 const std::shared_ptr<Capabilities>& capabilities) {
330 return pimpl_->screenshotter->GetPlayground().SetCapabilities(capabilities);
331}
332
333std::unique_ptr<testing::Screenshot> GoldenPlaygroundTest::MakeScreenshot(
334 const sk_sp<flutter::DisplayList>& list) {
335 AiksContext renderer(GetContext(), typographer_context_);
336 Point content_scale =
337 pimpl_->screenshotter->GetPlayground().GetContentScale();
338
339 ISize physical_window_size(
340 std::round(pimpl_->window_size.width * content_scale.x),
341 std::round(pimpl_->window_size.height * content_scale.y));
342 return pimpl_->screenshotter->MakeScreenshot(
344}
345
346}
FlutterDesktopBinaryReply callback
#define FML_LOG(severity)
#define FML_CHECK(condition)
#define IMP_AIKSTEST(name)
const char * GetTestingAssetsPath()
Returns the directory containing assets shared across all tests.
std::unique_ptr< fml::Mapping > OpenFixtureAsMapping(const std::string &fixture_name)
Opens a fixture of the given file name and returns a mapping to its contents.
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
std::shared_ptr< Texture > DisplayListToTexture(const sk_sp< flutter::DisplayList > &display_list, ISize size, AiksContext &context, bool reset_host_buffer, bool generate_mips)
Render the provided display list to a texture with the given size.
static const std::vector< std::string > kSkipTests