| Flutter Impeller |

golden_playground_test_mac.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 #include <dlfcn.h>
6 #include <filesystem>
7 #include <memory>
8
9 #include "flutter/impeller/golden_tests/golden_playground_test.h"
10
11 #include "flutter/impeller/aiks/picture.h"
12 #include "flutter/impeller/golden_tests/golden_digest.h"
13 #include "flutter/impeller/golden_tests/metal_screenshoter.h"
14 #include "impeller/typographer/backends/skia/typographer_context_skia.h"
15 #include "impeller/typographer/typographer_context.h"
16
17 namespace impeller {
18
19 // If you add a new playground test to the aiks unittests and you do not want it
20 // to also be a golden test, then add the test name here.
21 static const std::vector<std::string> kSkipTests = {
22 "impeller_Play_AiksTest_CanDrawPaintMultipleTimesInteractive_Metal",
23 "impeller_Play_AiksTest_CanDrawPaintMultipleTimesInteractive_Vulkan",
24 "impeller_Play_AiksTest_CanRenderLinearGradientManyColorsUnevenStops_Metal",
25 "impeller_Play_AiksTest_CanRenderLinearGradientManyColorsUnevenStops_"
26 "Vulkan",
27 "impeller_Play_AiksTest_CanRenderRadialGradient_Metal",
28 "impeller_Play_AiksTest_CanRenderRadialGradient_Vulkan",
29 "impeller_Play_AiksTest_CanRenderRadialGradientManyColors_Metal",
30 "impeller_Play_AiksTest_CanRenderRadialGradientManyColors_Vulkan",
31 "impeller_Play_AiksTest_CanRenderBackdropBlurInteractive_Metal",
32 "impeller_Play_AiksTest_CanRenderBackdropBlurInteractive_Vulkan",
33 "impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectlyInteractive_Metal",
34 "impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectlyInteractive_"
35 "Vulkan",
36 "impeller_Play_AiksTest_TextFrameSubpixelAlignment_Metal",
37 "impeller_Play_AiksTest_TextFrameSubpixelAlignment_Vulkan",
38 "impeller_Play_AiksTest_ColorWheel_Metal",
39 "impeller_Play_AiksTest_ColorWheel_Vulkan",
40 "impeller_Play_AiksTest_SolidStrokesRenderCorrectly_Metal",
41 "impeller_Play_AiksTest_SolidStrokesRenderCorrectly_Vulkan",
42 "impeller_Play_AiksTest_GradientStrokesRenderCorrectly_Metal",
43 "impeller_Play_AiksTest_GradientStrokesRenderCorrectly_Vulkan",
44 "impeller_Play_AiksTest_CoverageOriginShouldBeAccountedForInSubpasses_"
45 "Metal",
46 "impeller_Play_AiksTest_CoverageOriginShouldBeAccountedForInSubpasses_"
47 "Vulkan",
48 "impeller_Play_AiksTest_SceneColorSource_Metal",
49 "impeller_Play_AiksTest_SceneColorSource_Vulkan",
50 // TextRotated is flakey and we can't seem to get it to stabilize on Skia
51 // Gold.
52 "impeller_Play_AiksTest_TextRotated_Metal",
53 "impeller_Play_AiksTest_TextRotated_Vulkan",
54 };
55
56 namespace {
57 std::string GetTestName() {
58 std::string suite_name =
59 ::testing::UnitTest::GetInstance()->current_test_suite()->name();
60 std::string test_name =
61 ::testing::UnitTest::GetInstance()->current_test_info()->name();
62 std::stringstream ss;
63 ss << "impeller_" << suite_name << "_" << test_name;
64 std::string result = ss.str();
65 // Make sure there are no slashes in the test name.
66 std::replace(result.begin(), result.end(), '/', '_');
67 return result;
68 }
69
70 std::string GetGoldenFilename() {
71 return GetTestName() + ".png";
72 }
73
74 bool SaveScreenshot(std::unique_ptr<testing::MetalScreenshot> screenshot) {
75 if (!screenshot || !screenshot->GetBytes()) {
76 return false;
77 }
78 std::string test_name = GetTestName();
79 std::string filename = GetGoldenFilename();
80 testing::GoldenDigest::Instance()->AddImage(
81 test_name, filename, screenshot->GetWidth(), screenshot->GetHeight());
82 return screenshot->WriteToPNG(
83 testing::WorkingDirectory::Instance()->GetFilenamePath(filename));
84 }
85 } // namespace
86
87 struct GoldenPlaygroundTest::GoldenPlaygroundTestImpl {
88 GoldenPlaygroundTestImpl() : screenshoter(new testing::MetalScreenshoter()) {}
89 std::unique_ptr<testing::MetalScreenshoter> screenshoter;
90 ISize window_size = ISize{1024, 768};
91 };
92
93 GoldenPlaygroundTest::GoldenPlaygroundTest()
94 : typographer_context_(TypographerContextSkia::Make()),
95 pimpl_(new GoldenPlaygroundTest::GoldenPlaygroundTestImpl()) {}
96
97 GoldenPlaygroundTest::~GoldenPlaygroundTest() = default;
98
99 void GoldenPlaygroundTest::SetTypographerContext(
100 std::shared_ptr<TypographerContext> typographer_context) {
101 typographer_context_ = std::move(typographer_context);
102 };
103
104 void GoldenPlaygroundTest::TearDown() {
105 ASSERT_FALSE(dlopen("/usr/local/lib/libMoltenVK.dylib", RTLD_NOLOAD));
106 }
107
108 void GoldenPlaygroundTest::SetUp() {
109 std::filesystem::path testing_assets_path =
110 flutter::testing::GetTestingAssetsPath();
111 std::filesystem::path target_path = testing_assets_path.parent_path()
112 .parent_path()
113 .parent_path()
114 .parent_path();
115 std::filesystem::path icd_path = target_path / "vk_swiftshader_icd.json";
116 setenv("VK_ICD_FILENAMES", icd_path.c_str(), 1);
117
118 if (GetBackend() != PlaygroundBackend::kMetal &&
119 GetBackend() != PlaygroundBackend::kVulkan) {
120 GTEST_SKIP_("GoldenPlaygroundTest doesn't support this backend type.");
121 return;
122 }
123
124 std::string test_name = GetTestName();
125 if (std::find(kSkipTests.begin(), kSkipTests.end(), test_name) !=
126 kSkipTests.end()) {
127 GTEST_SKIP_(
128 "GoldenPlaygroundTest doesn't support interactive playground tests "
129 "yet.");
130 }
131
132 testing::GoldenDigest::Instance()->AddDimension(
133 "gpu_string", GetContext()->DescribeGpuModel());
134 }
135
136 PlaygroundBackend GoldenPlaygroundTest::GetBackend() const {
137 return GetParam();
138 }
139
140 bool GoldenPlaygroundTest::OpenPlaygroundHere(Picture picture) {
141 AiksContext renderer(GetContext(), typographer_context_);
142
143 auto screenshot = pimpl_->screenshoter->MakeScreenshot(renderer, picture,
144 pimpl_->window_size);
145 return SaveScreenshot(std::move(screenshot));
146 }
147
148 bool GoldenPlaygroundTest::OpenPlaygroundHere(
149 AiksPlaygroundCallback
150 callback) { // NOLINT(performance-unnecessary-value-param)
151 return false;
152 }
153
154 std::shared_ptr<Texture> GoldenPlaygroundTest::CreateTextureForFixture(
155 const char* fixture_name,
156 bool enable_mipmapping) const {
157 std::shared_ptr<fml::Mapping> mapping =
158 flutter::testing::OpenFixtureAsMapping(fixture_name);
159 auto result = Playground::CreateTextureForMapping(GetContext(), mapping,
160 enable_mipmapping);
161 if (result) {
162 result->SetLabel(fixture_name);
163 }
164 return result;
165 }
166
167 std::shared_ptr<RuntimeStage> GoldenPlaygroundTest::OpenAssetAsRuntimeStage(
168 const char* asset_name) const {
169 auto fixture = flutter::testing::OpenFixtureAsMapping(asset_name);
170 if (!fixture || fixture->GetSize() == 0) {
171 return nullptr;
172 }
173 auto stage = std::make_unique<RuntimeStage>(std::move(fixture));
174 if (!stage->IsValid()) {
175 return nullptr;
176 }
177 return stage;
178 }
179
180 std::shared_ptr<Context> GoldenPlaygroundTest::GetContext() const {
181 return pimpl_->screenshoter->GetPlayground().GetContext();
182 }
183
184 Point GoldenPlaygroundTest::GetContentScale() const {
185 return pimpl_->screenshoter->GetPlayground().GetContentScale();
186 }
187
188 Scalar GoldenPlaygroundTest::GetSecondsElapsed() const {
189 return 0.0f;
190 }
191
192 ISize GoldenPlaygroundTest::GetWindowSize() const {
193 return pimpl_->window_size;
194 }
195
196 } // namespace impeller
impeller::GoldenPlaygroundTest::GetContentScale
Point GetContentScale() const
Definition: golden_playground_test_mac.cc:184
impeller::GoldenPlaygroundTest::AiksPlaygroundCallback
std::function< std::optional< Picture >(AiksContext &renderer)> AiksPlaygroundCallback
Definition: golden_playground_test.h:26
impeller::PlaygroundBackend::kVulkan
@ kVulkan
impeller::Scalar
float Scalar
Definition: scalar.h:15
impeller::AiksContext
Definition: aiks_context.h:20
golden_digest.h
impeller::PlaygroundBackend::kMetal
@ kMetal
impeller::PlaygroundBackend
PlaygroundBackend
Definition: playground.h:25
impeller::GoldenPlaygroundTest::OpenPlaygroundHere
bool OpenPlaygroundHere(Picture picture)
Definition: golden_playground_test_mac.cc:140
typographer_context.h
metal_screenshoter.h
picture.h
impeller::testing::GoldenDigest::AddImage
void AddImage(const std::string &test_name, const std::string &filename, int32_t width, int32_t height)
Definition: golden_digest.cc:34
impeller::GoldenPlaygroundTest::GetContext
std::shared_ptr< Context > GetContext() const
Definition: golden_playground_test_mac.cc:180
impeller::GoldenPlaygroundTest::GoldenPlaygroundTestImpl
Definition: golden_playground_test_mac.cc:87
impeller::GoldenPlaygroundTest::~GoldenPlaygroundTest
~GoldenPlaygroundTest() override
typographer_context_skia.h
impeller::GoldenPlaygroundTest::SetTypographerContext
void SetTypographerContext(std::shared_ptr< TypographerContext > typographer_context)
Definition: golden_playground_test_mac.cc:99
impeller::Picture
Definition: picture.h:19
impeller::TSize< int64_t >
impeller::GoldenPlaygroundTest::GoldenPlaygroundTest
GoldenPlaygroundTest()
Definition: golden_playground_test_mac.cc:93
impeller::GoldenPlaygroundTest::GetBackend
PlaygroundBackend GetBackend() const
Definition: golden_playground_test_mac.cc:136
impeller::kSkipTests
static const std::vector< std::string > kSkipTests
Definition: golden_playground_test_mac.cc:21
impeller::GoldenPlaygroundTest::SetUp
void SetUp()
Definition: golden_playground_test_mac.cc:108
impeller::GoldenPlaygroundTest
Definition: golden_playground_test.h:22
impeller::GoldenPlaygroundTest::GoldenPlaygroundTestImpl::screenshoter
std::unique_ptr< testing::MetalScreenshoter > screenshoter
Definition: golden_playground_test_mac.cc:89
impeller::GoldenPlaygroundTest::OpenAssetAsRuntimeStage
std::shared_ptr< RuntimeStage > OpenAssetAsRuntimeStage(const char *asset_name) const
Definition: golden_playground_test_mac.cc:167
impeller::GoldenPlaygroundTest::CreateTextureForFixture
std::shared_ptr< Texture > CreateTextureForFixture(const char *fixture_name, bool enable_mipmapping=false) const
Definition: golden_playground_test_mac.cc:154
golden_playground_test.h
impeller::TypographerContextSkia
Definition: typographer_context_skia.h:12
impeller::Playground::CreateTextureForMapping
static std::shared_ptr< Texture > CreateTextureForMapping(const std::shared_ptr< Context > &context, std::shared_ptr< fml::Mapping > mapping, bool enable_mipmapping=false)
Definition: playground.cc:461
impeller::GoldenPlaygroundTest::GetSecondsElapsed
Scalar GetSecondsElapsed() const
Definition: golden_playground_test_mac.cc:188
impeller::GoldenPlaygroundTest::TearDown
void TearDown()
Definition: golden_playground_test_mac.cc:104
impeller::TPoint< Scalar >
impeller::testing::GoldenDigest::Instance
static GoldenDigest * Instance()
Definition: golden_digest.cc:18
impeller::testing::GoldenDigest::AddDimension
void AddDimension(const std::string &name, const std::string &value)
Definition: golden_digest.cc:27
impeller::testing::WorkingDirectory::Instance
static WorkingDirectory * Instance()
Definition: working_directory.cc:16
impeller::GoldenPlaygroundTest::GoldenPlaygroundTestImpl::window_size
ISize window_size
Definition: golden_playground_test_mac.cc:90
impeller
Definition: aiks_context.cc:10
impeller::GoldenPlaygroundTest::GetWindowSize
ISize GetWindowSize() const
Definition: golden_playground_test_mac.cc:192
impeller::GoldenPlaygroundTest::GoldenPlaygroundTestImpl::GoldenPlaygroundTestImpl
GoldenPlaygroundTestImpl()
Definition: golden_playground_test_mac.cc:88