| 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_screenshotter.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_CoverageOriginShouldBeAccountedForInSubpasses_"
37 "Metal",
38 "impeller_Play_AiksTest_CoverageOriginShouldBeAccountedForInSubpasses_"
39 "Vulkan",
40 "impeller_Play_AiksTest_GaussianBlurRotatedAndClippedInteractive_Metal",
41 "impeller_Play_AiksTest_GaussianBlurRotatedAndClippedInteractive_Vulkan",
42 "impeller_Play_AiksTest_GradientStrokesRenderCorrectly_Metal",
43 "impeller_Play_AiksTest_GradientStrokesRenderCorrectly_Vulkan",
44 "impeller_Play_AiksTest_ColorWheel_Metal",
45 "impeller_Play_AiksTest_ColorWheel_Vulkan",
46 "impeller_Play_AiksTest_SceneColorSource_Metal",
47 "impeller_Play_AiksTest_SceneColorSource_Vulkan",
48 "impeller_Play_AiksTest_SolidStrokesRenderCorrectly_Metal",
49 "impeller_Play_AiksTest_SolidStrokesRenderCorrectly_Vulkan",
50 "impeller_Play_AiksTest_TextFrameSubpixelAlignment_Metal",
51 "impeller_Play_AiksTest_TextFrameSubpixelAlignment_Vulkan",
52 // TextRotated is flakey and we can't seem to get it to stabilize on Skia
53 // Gold.
54 "impeller_Play_AiksTest_TextRotated_Metal",
55 "impeller_Play_AiksTest_TextRotated_Vulkan",
56 };
57
58 namespace {
59 std::string GetTestName() {
60 std::string suite_name =
61 ::testing::UnitTest::GetInstance()->current_test_suite()->name();
62 std::string test_name =
63 ::testing::UnitTest::GetInstance()->current_test_info()->name();
64 std::stringstream ss;
65 ss << "impeller_" << suite_name << "_" << test_name;
66 std::string result = ss.str();
67 // Make sure there are no slashes in the test name.
68 std::replace(result.begin(), result.end(), '/', '_');
69 return result;
70 }
71
72 std::string GetGoldenFilename() {
73 return GetTestName() + ".png";
74 }
75
76 bool SaveScreenshot(std::unique_ptr<testing::MetalScreenshot> screenshot) {
77 if (!screenshot || !screenshot->GetBytes()) {
78 return false;
79 }
80 std::string test_name = GetTestName();
81 std::string filename = GetGoldenFilename();
82 testing::GoldenDigest::Instance()->AddImage(
83 test_name, filename, screenshot->GetWidth(), screenshot->GetHeight());
84 return screenshot->WriteToPNG(
85 testing::WorkingDirectory::Instance()->GetFilenamePath(filename));
86 }
87 } // namespace
88
89 struct GoldenPlaygroundTest::GoldenPlaygroundTestImpl {
90 GoldenPlaygroundTestImpl()
91 : screenshotter(new testing::MetalScreenshotter()) {}
92 std::unique_ptr<testing::MetalScreenshotter> screenshotter;
93 ISize window_size = ISize{1024, 768};
94 };
95
96 GoldenPlaygroundTest::GoldenPlaygroundTest()
97 : typographer_context_(TypographerContextSkia::Make()),
98 pimpl_(new GoldenPlaygroundTest::GoldenPlaygroundTestImpl()) {}
99
100 GoldenPlaygroundTest::~GoldenPlaygroundTest() = default;
101
102 void GoldenPlaygroundTest::SetTypographerContext(
103 std::shared_ptr<TypographerContext> typographer_context) {
104 typographer_context_ = std::move(typographer_context);
105 };
106
107 void GoldenPlaygroundTest::TearDown() {
108 ASSERT_FALSE(dlopen("/usr/local/lib/libMoltenVK.dylib", RTLD_NOLOAD));
109 }
110
111 void GoldenPlaygroundTest::SetUp() {
112 std::filesystem::path testing_assets_path =
113 flutter::testing::GetTestingAssetsPath();
114 std::filesystem::path target_path = testing_assets_path.parent_path()
115 .parent_path()
116 .parent_path()
117 .parent_path();
118 std::filesystem::path icd_path = target_path / "vk_swiftshader_icd.json";
119 setenv("VK_ICD_FILENAMES", icd_path.c_str(), 1);
120
121 if (GetBackend() != PlaygroundBackend::kMetal &&
122 GetBackend() != PlaygroundBackend::kVulkan) {
123 GTEST_SKIP_("GoldenPlaygroundTest doesn't support this backend type.");
124 return;
125 }
126
127 std::string test_name = GetTestName();
128 if (std::find(kSkipTests.begin(), kSkipTests.end(), test_name) !=
129 kSkipTests.end()) {
130 GTEST_SKIP_(
131 "GoldenPlaygroundTest doesn't support interactive playground tests "
132 "yet.");
133 }
134
135 testing::GoldenDigest::Instance()->AddDimension(
136 "gpu_string", GetContext()->DescribeGpuModel());
137 }
138
139 PlaygroundBackend GoldenPlaygroundTest::GetBackend() const {
140 return GetParam();
141 }
142
143 bool GoldenPlaygroundTest::OpenPlaygroundHere(Picture picture) {
144 AiksContext renderer(GetContext(), typographer_context_);
145
146 auto screenshot = pimpl_->screenshotter->MakeScreenshot(renderer, picture,
147 pimpl_->window_size);
148 return SaveScreenshot(std::move(screenshot));
149 }
150
151 bool GoldenPlaygroundTest::OpenPlaygroundHere(
152 AiksPlaygroundCallback
153 callback) { // NOLINT(performance-unnecessary-value-param)
154 return false;
155 }
156
157 std::shared_ptr<Texture> GoldenPlaygroundTest::CreateTextureForFixture(
158 const char* fixture_name,
159 bool enable_mipmapping) const {
160 std::shared_ptr<fml::Mapping> mapping =
161 flutter::testing::OpenFixtureAsMapping(fixture_name);
162 auto result = Playground::CreateTextureForMapping(GetContext(), mapping,
163 enable_mipmapping);
164 if (result) {
165 result->SetLabel(fixture_name);
166 }
167 return result;
168 }
169
170 RuntimeStage::Map GoldenPlaygroundTest::OpenAssetAsRuntimeStage(
171 const char* asset_name) const {
172 const std::shared_ptr<fml::Mapping> fixture =
173 flutter::testing::OpenFixtureAsMapping(asset_name);
174 if (!fixture || fixture->GetSize() == 0) {
175 return {};
176 }
177 return RuntimeStage::DecodeRuntimeStages(fixture);
178 }
179
180 std::shared_ptr<Context> GoldenPlaygroundTest::GetContext() const {
181 return pimpl_->screenshotter->GetPlayground().GetContext();
182 }
183
184 Point GoldenPlaygroundTest::GetContentScale() const {
185 return pimpl_->screenshotter->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 void GoldenPlaygroundTest::GoldenPlaygroundTest::SetWindowSize(ISize size) {
197 pimpl_->window_size = size;
198 }
199
200 fml::Status GoldenPlaygroundTest::SetCapabilities(
201 const std::shared_ptr<Capabilities>& capabilities) {
202 return pimpl_->screenshotter->GetPlayground().SetCapabilities(capabilities);
203 }
204
205 } // 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:27
impeller::PlaygroundBackend::kVulkan
@ kVulkan
impeller::GoldenPlaygroundTest::SetCapabilities
fml::Status SetCapabilities(const std::shared_ptr< Capabilities > &capabilities)
Definition: golden_playground_test_mac.cc:200
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::AiksContext
Definition: aiks_context.h:20
golden_digest.h
impeller::RuntimeStage::DecodeRuntimeStages
static Map DecodeRuntimeStages(const std::shared_ptr< fml::Mapping > &payload)
Definition: runtime_stage.cc:72
impeller::PlaygroundBackend::kMetal
@ kMetal
impeller::PlaygroundBackend
PlaygroundBackend
Definition: playground.h:29
impeller::GoldenPlaygroundTest::OpenPlaygroundHere
bool OpenPlaygroundHere(Picture picture)
Definition: golden_playground_test_mac.cc:143
typographer_context.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:89
impeller::GoldenPlaygroundTest::~GoldenPlaygroundTest
~GoldenPlaygroundTest() override
impeller::GoldenPlaygroundTest::GoldenPlaygroundTestImpl::screenshotter
std::unique_ptr< testing::MetalScreenshotter > screenshotter
Definition: golden_playground_test_mac.cc:92
typographer_context_skia.h
impeller::GoldenPlaygroundTest::SetTypographerContext
void SetTypographerContext(std::shared_ptr< TypographerContext > typographer_context)
Definition: golden_playground_test_mac.cc:102
impeller::Picture
Definition: picture.h:20
impeller::TSize< int64_t >
impeller::GoldenPlaygroundTest::GoldenPlaygroundTest
GoldenPlaygroundTest()
Definition: golden_playground_test_mac.cc:96
impeller::GoldenPlaygroundTest::GetBackend
PlaygroundBackend GetBackend() const
Definition: golden_playground_test_mac.cc:139
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:111
impeller::GoldenPlaygroundTest
Definition: golden_playground_test.h:23
impeller::GoldenPlaygroundTest::CreateTextureForFixture
std::shared_ptr< Texture > CreateTextureForFixture(const char *fixture_name, bool enable_mipmapping=false) const
Definition: golden_playground_test_mac.cc:157
golden_playground_test.h
impeller::TypographerContextSkia
Definition: typographer_context_skia.h:13
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:107
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:93
metal_screenshotter.h
impeller
Definition: aiks_context.cc:10
impeller::GoldenPlaygroundTest::GetWindowSize
ISize GetWindowSize() const
Definition: golden_playground_test_mac.cc:192
impeller::GoldenPlaygroundTest::OpenAssetAsRuntimeStage
RuntimeStage::Map OpenAssetAsRuntimeStage(const char *asset_name) const
Definition: golden_playground_test_mac.cc:170
impeller::RuntimeStage::Map
std::map< RuntimeStageBackend, std::shared_ptr< RuntimeStage > > Map
Definition: runtime_stage.h:22
impeller::GoldenPlaygroundTest::GoldenPlaygroundTestImpl::GoldenPlaygroundTestImpl
GoldenPlaygroundTestImpl()
Definition: golden_playground_test_mac.cc:90