9 #include "display_list/display_list.h"
15 #include "flutter/third_party/abseil-cpp/absl/base/no_destructor.h"
16 #include "fml/closure.h"
23 #define GLFW_INCLUDE_NONE
24 #include "third_party/glfw/include/GLFW/glfw3.h"
29 std::unique_ptr<PlaygroundImpl> MakeVulkanPlayground(
bool enable_validations) {
30 FML_CHECK(::glfwInit() == GLFW_TRUE);
31 PlaygroundSwitches playground_switches;
32 playground_switches.enable_vulkan_validation = enable_validations;
38 const std::unique_ptr<PlaygroundImpl>& GetSharedVulkanPlayground(
39 bool enable_validations) {
40 if (enable_validations) {
41 static absl::NoDestructor<std::unique_ptr<PlaygroundImpl>>
42 vulkan_validation_playground(
43 MakeVulkanPlayground(
true));
46 static fml::ScopedCleanupClosure context_cleanup(
47 [&] { (*vulkan_validation_playground)->GetContext()->Shutdown(); });
48 return *vulkan_validation_playground;
50 static absl::NoDestructor<std::unique_ptr<PlaygroundImpl>>
51 vulkan_playground(MakeVulkanPlayground(
false));
54 static fml::ScopedCleanupClosure context_cleanup(
55 [&] { (*vulkan_playground)->GetContext()->Shutdown(); });
56 return *vulkan_playground;
62 #define IMP_AIKSTEST(name) \
63 "impeller_Play_AiksTest_" #name "_Metal", \
64 "impeller_Play_AiksTest_" #name "_OpenGLES", \
65 "impeller_Play_AiksTest_" #name "_Vulkan"
74 "impeller_Play_AiksTest_CanRenderClippedRuntimeEffects_Vulkan",
78 std::string GetTestName() {
79 std::string suite_name =
80 ::testing::UnitTest::GetInstance()->current_test_suite()->name();
81 std::string test_name =
82 ::testing::UnitTest::GetInstance()->current_test_info()->name();
84 ss <<
"impeller_" << suite_name <<
"_" << test_name;
85 std::string result = ss.str();
87 std::replace(result.begin(), result.end(),
'/',
'_');
91 std::string GetGoldenFilename(
const std::string& postfix) {
92 return GetTestName() + postfix +
".png";
97 std::unique_ptr<testing::Screenshot> screenshot,
98 const std::string& postfix) {
99 if (!screenshot || !screenshot->GetBytes()) {
100 FML_LOG(ERROR) <<
"Failed to collect screenshot for test " << GetTestName();
103 std::string test_name = GetTestName();
104 std::string filename = GetGoldenFilename(postfix);
106 test_name, filename, screenshot->GetWidth(), screenshot->GetHeight());
107 if (!screenshot->WriteToPNG(
109 FML_LOG(ERROR) <<
"Failed to write screenshot to " << filename;
129 std::shared_ptr<TypographerContext> typographer_context) {
130 typographer_context_ = std::move(typographer_context);
134 ASSERT_FALSE(dlopen(
"/usr/local/lib/libMoltenVK.dylib", RTLD_NOLOAD));
138 context->DisposeThreadLocalCachedResources();
143 bool DoesSupportWideGamutTests() {
153 std::filesystem::path testing_assets_path =
154 flutter::testing::GetTestingAssetsPath();
155 std::filesystem::path target_path = testing_assets_path.parent_path()
159 std::filesystem::path icd_path = target_path /
"vk_swiftshader_icd.json";
160 setenv(
"VK_ICD_FILENAMES", icd_path.c_str(), 1);
162 std::string test_name = GetTestName();
165 test_name.find(
"WideGamut_") != std::string::npos;
167 test_name.find(
"ExperimentAntialiasLines_") != std::string::npos;
168 switch (GetParam()) {
170 if (!DoesSupportWideGamutTests()) {
172 <<
"This metal device doesn't support wide gamut golden tests.";
174 pimpl_->screenshotter =
175 std::make_unique<testing::MetalScreenshotter>(switches);
179 GTEST_SKIP() <<
"Vulkan doesn't support wide gamut golden tests.";
183 <<
"Vulkan doesn't support antialiased lines golden tests.";
185 const std::unique_ptr<PlaygroundImpl>& playground =
186 GetSharedVulkanPlayground(
true);
187 pimpl_->screenshotter =
188 std::make_unique<testing::VulkanScreenshotter>(playground);
193 GTEST_SKIP() <<
"OpenGLES doesn't support wide gamut golden tests.";
197 <<
"OpenGLES doesn't support antialiased lines golden tests.";
199 FML_CHECK(::glfwInit() == GLFW_TRUE);
204 pimpl_->screenshotter = std::make_unique<testing::VulkanScreenshotter>(
205 pimpl_->test_opengl_playground);
213 <<
"GoldenPlaygroundTest doesn't support interactive playground tests "
218 "gpu_string",
GetContext()->DescribeGpuModel());
229 std::unique_ptr<testing::Screenshot> screenshot;
230 Point content_scale =
231 pimpl_->screenshotter->GetPlayground().GetContentScale();
233 ISize physical_window_size(
234 std::round(pimpl_->window_size.width * content_scale.
x),
235 std::round(pimpl_->window_size.height * content_scale.
y));
236 for (
int i = 0; i < 2; ++i) {
237 auto display_list = callback();
240 screenshot = pimpl_->screenshotter->MakeScreenshot(renderer, texture);
246 const sk_sp<flutter::DisplayList>& list) {
252 ImGuiWindowFlags flags) {
257 const char* fixture_name,
258 bool enable_mipmapping)
const {
259 std::shared_ptr<fml::Mapping> mapping =
260 flutter::testing::OpenFixtureAsMapping(fixture_name);
264 result->SetLabel(fixture_name);
270 const char* fixture_name,
271 bool enable_mipmapping)
const {
272 std::shared_ptr<Texture> texture =
278 const char* asset_name)
const {
279 const std::shared_ptr<fml::Mapping> fixture =
280 flutter::testing::OpenFixtureAsMapping(asset_name);
281 if (!fixture || fixture->GetSize() == 0) {
288 if (!pimpl_->screenshotter) {
291 return pimpl_->screenshotter->GetPlayground().GetContext();
299 bool enable_vulkan_validations =
true;
300 FML_CHECK(!pimpl_->test_vulkan_playground)
301 <<
"We don't support creating multiple contexts for one test";
302 pimpl_->test_vulkan_playground =
303 MakeVulkanPlayground(enable_vulkan_validations);
304 pimpl_->screenshotter = std::make_unique<testing::VulkanScreenshotter>(
305 pimpl_->test_vulkan_playground);
306 return pimpl_->test_vulkan_playground->GetContext();
314 return pimpl_->screenshotter->GetPlayground().GetContentScale();
322 return pimpl_->window_size;
325 void GoldenPlaygroundTest::GoldenPlaygroundTest::SetWindowSize(
ISize size) {
326 pimpl_->window_size = size;
330 const std::shared_ptr<Capabilities>& capabilities) {
331 return pimpl_->screenshotter->GetPlayground().SetCapabilities(capabilities);
335 const sk_sp<flutter::DisplayList>& list) {
337 Point content_scale =
338 pimpl_->screenshotter->GetPlayground().GetContentScale();
340 ISize physical_window_size(
341 std::round(pimpl_->window_size.width * content_scale.
x),
342 std::round(pimpl_->window_size.height * content_scale.
y));
343 return pimpl_->screenshotter->MakeScreenshot(
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
PlaygroundBackend GetBackend() const
ISize GetWindowSize() const
sk_sp< flutter::DlImage > CreateDlImageForFixture(const char *fixture_name, bool enable_mipmapping=false) const
Point GetContentScale() const
fml::Status SetCapabilities(const std::shared_ptr< Capabilities > &capabilities)
void SetTypographerContext(std::shared_ptr< TypographerContext > typographer_context)
std::shared_ptr< Context > MakeContext() const
static bool SaveScreenshot(std::unique_ptr< testing::Screenshot > screenshot, const std::string &postfix="")
std::unique_ptr< testing::Screenshot > MakeScreenshot(const sk_sp< flutter::DisplayList > &list)
Scalar GetSecondsElapsed() const
RuntimeStage::Map OpenAssetAsRuntimeStage(const char *asset_name) const
bool OpenPlaygroundHere(Picture picture)
static bool ImGuiBegin(const char *name, bool *p_open, ImGuiWindowFlags flags)
std::function< sk_sp< flutter::DisplayList >()> AiksDlPlaygroundCallback
~GoldenPlaygroundTest() override
std::shared_ptr< Context > GetContext() const
std::shared_ptr< Texture > CreateTextureForFixture(const char *fixture_name, bool enable_mipmapping=false) const
static std::shared_ptr< Texture > CreateTextureForMapping(const std::shared_ptr< Context > &context, std::shared_ptr< fml::Mapping > mapping, bool enable_mipmapping=false)
static std::unique_ptr< PlaygroundImpl > Create(PlaygroundBackend backend, PlaygroundSwitches switches)
std::map< RuntimeStageBackend, std::shared_ptr< RuntimeStage > > Map
static Map DecodeRuntimeStages(const std::shared_ptr< fml::Mapping > &payload)
static GoldenDigest * Instance()
void AddDimension(const std::string &name, const std::string &value)
void AddImage(const std::string &test_name, const std::string &filename, int32_t width, int32_t height)
std::string GetFilenamePath(const std::string &filename) const
static WorkingDirectory * Instance()
#define IMP_AIKSTEST(name)
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
bool antialiased_lines
When turned on DrawLine will use the experimental antialiased path.
std::unique_ptr< PlaygroundImpl > test_vulkan_playground
std::unique_ptr< testing::Screenshotter > screenshotter
std::unique_ptr< PlaygroundImpl > test_opengl_playground