Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
aiks_dl_atlas_unittests.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
11
23
24namespace impeller {
25namespace testing {
26
27using namespace flutter;
28
29namespace {
30RSTransform MakeTranslation(Scalar tx, Scalar ty) {
31 return RSTransform::Make({tx, ty}, 1, DlDegrees(0));
32}
33
34std::tuple<std::vector<DlRect>, //
35 std::vector<RSTransform>, //
36 sk_sp<DlImageImpeller>>
37CreateTestData(const AiksTest* test) {
38 // Draws the image as four squares stiched together.
39 auto atlas =
40 DlImageImpeller::Make(test->CreateTextureForFixture("bay_bridge.jpg"));
41 auto size = atlas->GetImpellerTexture(test->GetContext())->GetSize();
42 // Divide image into four quadrants.
43 Scalar half_width = size.width / 2;
44 Scalar half_height = size.height / 2;
45 std::vector<DlRect> texture_coordinates = {
46 DlRect::MakeLTRB(0, 0, half_width, half_height),
47 DlRect::MakeLTRB(half_width, 0, size.width, half_height),
48 DlRect::MakeLTRB(0, half_height, half_width, size.height),
49 DlRect::MakeLTRB(half_width, half_height, size.width, size.height)};
50 // Position quadrants adjacent to eachother.
51 std::vector<RSTransform> transforms = {
52 MakeTranslation(0, 0), MakeTranslation(half_width, 0),
53 MakeTranslation(0, half_height),
54 MakeTranslation(half_width, half_height)};
55 return std::make_tuple(texture_coordinates, transforms, atlas);
56}
57
58} // namespace
59
60TEST_P(AiksTest, DrawAtlasNoColor) {
61 DisplayListBuilder builder;
62 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
63
64 builder.Scale(GetContentScale().x, GetContentScale().y);
65 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
66 /*colors=*/nullptr, /*count=*/4, DlBlendMode::kSrcOver,
67 DlImageSampling::kNearestNeighbor, nullptr);
68
69 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
70}
71
72TEST_P(AiksTest, DrawAtlasWithColorAdvanced) {
73 DisplayListBuilder builder;
74 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
75
76 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
78
79 builder.Scale(GetContentScale().x, GetContentScale().y);
80 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
81 colors.data(), /*count=*/4, DlBlendMode::kModulate,
82 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
83
84 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
85}
86
87TEST_P(AiksTest, DrawAtlasWithColorSimple) {
88 DisplayListBuilder builder;
89 // Draws the image as four squares stiched together.
90 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
91
92 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
94
95 builder.Scale(GetContentScale().x, GetContentScale().y);
96 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
97 colors.data(), /*count=*/4, DlBlendMode::kSrcATop,
98 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
99
100 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
101}
102
103TEST_P(AiksTest, DrawAtlasWithOpacity) {
104 DisplayListBuilder builder;
105 // Draws the image as four squares stiched together slightly
106 // opaque
107 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
108
109 DlPaint paint;
110 paint.setAlpha(128);
111 builder.Scale(GetContentScale().x, GetContentScale().y);
112 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
113 /*colors=*/nullptr, 4, DlBlendMode::kSrcOver,
114 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr,
115 &paint);
116
117 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
118}
119
120TEST_P(AiksTest, DrawAtlasNoColorFullSize) {
121 auto atlas = DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
122 auto size = atlas->GetImpellerTexture(GetContext())->GetSize();
123 std::vector<DlRect> texture_coordinates = {
124 DlRect::MakeLTRB(0, 0, size.width, size.height)};
125 std::vector<RSTransform> transforms = {MakeTranslation(0, 0)};
126
127 DisplayListBuilder builder;
128 builder.Scale(GetContentScale().x, GetContentScale().y);
129 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
130 /*colors=*/nullptr, /*count=*/1, DlBlendMode::kSrcOver,
131 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
132
133 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
134}
135
136// Regression test for https://github.com/flutter/flutter/issues/127374.
137TEST_P(AiksTest, DrawAtlasAdvancedAndTransform) {
138 DisplayListBuilder builder;
139 // Draws the image as four squares stiched together.
140 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
141
142 builder.Scale(0.25, 0.25);
143 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
144 /*colors=*/nullptr, /*count=*/4, DlBlendMode::kModulate,
145 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
146
147 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
148}
149
150// Regression test for https://github.com/flutter/flutter/issues/127374.
151TEST_P(AiksTest, DrawAtlasWithColorAdvancedAndTransform) {
152 DisplayListBuilder builder;
153 // Draws the image as four squares stiched together.
154 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
155 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
157
158 builder.Scale(0.25, 0.25);
159 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
160 colors.data(), /*count=*/4, DlBlendMode::kModulate,
161 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
162
163 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
164}
165
166TEST_P(AiksTest, DrawAtlasPlusWideGamut) {
167 // Must be called before any methods that use the context to ensure that
168 // this test is always run with wide gamut support.
169 if (!EnsureContextSupportsWideGamut()) {
170 GTEST_SKIP() << "This backend doesn't yet support wide gamut.";
171 }
172
173 DisplayListBuilder builder;
174 EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
176
177 // Draws the image as four squares stiched together.
178 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
179 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
181
182 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
183 colors.data(), /*count=*/4, DlBlendMode::kPlus,
184 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
185
186 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
187}
188
189TEST_P(AiksTest, DlAtlasGeometryNoBlendRenamed) {
190 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
191
192 DlAtlasGeometry geom(atlas->GetImpellerTexture(GetContext()),
193 transforms.data(), texture_coordinates.data(), nullptr,
194 transforms.size(), BlendMode::kSrcOver, {},
195 std::nullopt);
196
197 EXPECT_FALSE(geom.ShouldUseBlend());
198 EXPECT_FALSE(geom.ShouldSkip());
199
200 ContentContext context(GetContext(), nullptr);
201 auto vertex_buffer =
202 geom.CreateSimpleVertexBuffer(context.GetTransientsDataBuffer());
203
204 EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
205 EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
206}
207
208TEST_P(AiksTest, DlAtlasGeometryBlend) {
209 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
210
211 std::vector<DlColor> colors;
212 colors.reserve(texture_coordinates.size());
213 for (auto i = 0u; i < texture_coordinates.size(); i++) {
214 colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
215 }
216 DlAtlasGeometry geom(atlas->GetImpellerTexture(GetContext()),
217 transforms.data(), texture_coordinates.data(),
218 colors.data(), transforms.size(), BlendMode::kSrcOver,
219 {}, std::nullopt);
220
221 EXPECT_TRUE(geom.ShouldUseBlend());
222 EXPECT_FALSE(geom.ShouldSkip());
223
224 ContentContext context(GetContext(), nullptr);
225 auto vertex_buffer =
226 geom.CreateBlendVertexBuffer(context.GetTransientsDataBuffer());
227
228 EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
229 EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
230}
231
232TEST_P(AiksTest, DlAtlasGeometryColorButNoBlend) {
233 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
234
235 std::vector<DlColor> colors;
236 colors.reserve(texture_coordinates.size());
237 for (auto i = 0u; i < texture_coordinates.size(); i++) {
238 colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
239 }
240 DlAtlasGeometry geom(atlas->GetImpellerTexture(GetContext()),
241 transforms.data(), texture_coordinates.data(),
242 colors.data(), transforms.size(), BlendMode::kSrc, {},
243 std::nullopt);
244
245 // Src blend mode means that colors would be ignored, even if provided.
246 EXPECT_FALSE(geom.ShouldUseBlend());
247 EXPECT_FALSE(geom.ShouldSkip());
248}
249
250TEST_P(AiksTest, DlAtlasGeometrySkip) {
251 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
252
253 std::vector<DlColor> colors;
254 colors.reserve(texture_coordinates.size());
255 for (auto i = 0u; i < texture_coordinates.size(); i++) {
256 colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
257 }
258 DlAtlasGeometry geom(atlas->GetImpellerTexture(GetContext()),
259 transforms.data(), texture_coordinates.data(),
260 colors.data(), transforms.size(), BlendMode::kClear, {},
261 std::nullopt);
262 EXPECT_TRUE(geom.ShouldSkip());
263}
264
265TEST_P(AiksTest, DrawImageRectWithBlendColorFilter) {
266 sk_sp<DlImageImpeller> texture =
267 DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
268
269 DisplayListBuilder builder;
271 DlColor::kRed().withAlphaF(0.4), DlBlendMode::kSrcOver));
272
273 DlMatrix filter_matrix = DlMatrix();
274 auto filter = flutter::DlMatrixImageFilter(filter_matrix,
276 DlPaint paint_with_filter = paint;
277 paint_with_filter.setImageFilter(&filter);
278
279 // Compare porter-duff blend modes.
280 builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
281 // Uses image filter to disable atlas conversion.
282 builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
283 DlRect::MakeLTRB(0, 0, 500, 500), {},
284 &paint_with_filter);
285
286 // Uses atlas conversion.
287 builder.Translate(600, 0);
288 builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
289 DlRect::MakeLTRB(0, 0, 500, 500), {}, &paint);
290
291 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
292}
293
294TEST_P(AiksTest, DrawImageRectWithMatrixColorFilter) {
295 sk_sp<DlImageImpeller> texture =
296 DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
297
298 DisplayListBuilder builder;
299 static const constexpr ColorMatrix kColorInversion = {
300 .array = {
301 -1.0, 0, 0, 1.0, 0, //
302 0, -1.0, 0, 1.0, 0, //
303 0, 0, -1.0, 1.0, 0, //
304 1.0, 1.0, 1.0, 1.0, 0 //
305 }};
308
309 DlMatrix filter_matrix = DlMatrix();
310 auto filter = flutter::DlMatrixImageFilter(filter_matrix,
312 DlPaint paint_with_filter = paint;
313 paint_with_filter.setImageFilter(&filter);
314
315 // Compare inverting color matrix filter.
316 builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
317 // Uses image filter to disable atlas conversion.
318 builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
319 DlRect::MakeLTRB(0, 0, 500, 500), {},
320 &paint_with_filter);
321
322 // Uses atlas conversion.
323 builder.Translate(600, 0);
324 builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
325 DlRect::MakeLTRB(0, 0, 500, 500), {}, &paint);
326
327 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
328}
329
330TEST_P(AiksTest, DrawAtlasWithColorBurn) {
331 DisplayListBuilder builder;
332 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
333
334 std::vector<DlColor> colors = {DlColor::kDarkGrey(), DlColor::kBlack(),
336
337 builder.Scale(GetContentScale().x, GetContentScale().y);
338 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
339 colors.data(), /*count=*/4, DlBlendMode::kColorBurn,
340 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
341
342 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
343}
344
345} // namespace testing
346} // namespace impeller
void DrawImageRect(const sk_sp< DlImage > &image, const DlRect &src, const DlRect &dst, DlImageSampling sampling, const DlPaint *paint=nullptr, DlSrcRectConstraint constraint=DlSrcRectConstraint::kFast) override
void DrawAtlas(const sk_sp< DlImage > &atlas, const DlRSTransform xform[], const DlRect tex[], const DlColor colors[], int count, DlBlendMode mode, DlImageSampling sampling, const DlRect *cullRect, const DlPaint *paint=nullptr) override
void Scale(DlScalar sx, DlScalar sy) override
void Translate(DlScalar tx, DlScalar ty) override
void DrawPaint(const DlPaint &paint) override
sk_sp< DisplayList > Build()
static std::shared_ptr< const DlColorFilter > MakeBlend(DlColor color, DlBlendMode mode)
static std::shared_ptr< const DlColorFilter > MakeMatrix(const float matrix[20])
DlPaint & setAlpha(uint8_t alpha)
Definition dl_paint.h:76
DlPaint & setImageFilter(std::nullptr_t filter)
Definition dl_paint.h:167
DlPaint & setColorFilter(std::nullptr_t filter)
Definition dl_paint.h:149
A wrapper around data provided by a drawAtlas call.
VertexBuffer CreateBlendVertexBuffer(HostBuffer &host_buffer) const override
bool ShouldUseBlend() const override
Whether the blend shader should be used.
bool ShouldSkip() const override
VertexBuffer CreateSimpleVertexBuffer(HostBuffer &host_buffer) const override
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
int32_t x
FlTexture * texture
double y
impeller::Matrix DlMatrix
impeller::Degrees DlDegrees
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
AiksPlayground AiksTest
TEST_P(AiksTest, DrawAtlasNoColor)
float Scalar
Definition scalar.h:19
@ kNone
Does not use the index buffer.
static const constexpr ColorMatrix kColorInversion
A color matrix which inverts colors.
std::shared_ptr< ContextGLES > context
static constexpr DlColor kWhite()
Definition dl_color.h:70
static constexpr DlColor kBlue()
Definition dl_color.h:73
static constexpr DlColor kBlack()
Definition dl_color.h:69
static constexpr DlColor ARGB(DlScalar a, DlScalar r, DlScalar g, DlScalar b)
Construct a 32 bit color from floating point A, R, G, and B color channels.
Definition dl_color.h:57
static constexpr DlColor kYellow()
Definition dl_color.h:76
static constexpr DlColor kLightGrey()
Definition dl_color.h:79
static constexpr DlColor kRed()
Definition dl_color.h:71
static constexpr DlColor kGreen()
Definition dl_color.h:72
static constexpr DlColor kDarkGrey()
Definition dl_color.h:77
Scalar array[20]
Definition color.h:118
A 4x4 matrix using column-major storage.
Definition matrix.h:37
static RSTransform Make(Point origin, Scalar scale, Radians radians)
Definition rstransform.h:38
static constexpr TRect MakeSize(const TSize< U > &size)
Definition rect.h:150
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition rect.h:129