Flutter Engine
 
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>> CreateTestData(const AiksTest* test) {
37 // Draws the image as four squares stiched together.
38 auto atlas =
39 DlImageImpeller::Make(test->CreateTextureForFixture("bay_bridge.jpg"));
40 auto size = atlas->impeller_texture()->GetSize();
41 // Divide image into four quadrants.
42 Scalar half_width = size.width / 2;
43 Scalar half_height = size.height / 2;
44 std::vector<DlRect> texture_coordinates = {
45 DlRect::MakeLTRB(0, 0, half_width, half_height),
46 DlRect::MakeLTRB(half_width, 0, size.width, half_height),
47 DlRect::MakeLTRB(0, half_height, half_width, size.height),
48 DlRect::MakeLTRB(half_width, half_height, size.width, size.height)};
49 // Position quadrants adjacent to eachother.
50 std::vector<RSTransform> transforms = {
51 MakeTranslation(0, 0), MakeTranslation(half_width, 0),
52 MakeTranslation(0, half_height),
53 MakeTranslation(half_width, half_height)};
54 return std::make_tuple(texture_coordinates, transforms, atlas);
55}
56
57} // namespace
58
59TEST_P(AiksTest, DrawAtlasNoColor) {
60 DisplayListBuilder builder;
61 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
62
63 builder.Scale(GetContentScale().x, GetContentScale().y);
64 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
65 /*colors=*/nullptr, /*count=*/4, DlBlendMode::kSrcOver,
66 DlImageSampling::kNearestNeighbor, nullptr);
67
68 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
69}
70
71TEST_P(AiksTest, DrawAtlasWithColorAdvanced) {
72 DisplayListBuilder builder;
73 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
74
75 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
77
78 builder.Scale(GetContentScale().x, GetContentScale().y);
79 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
80 colors.data(), /*count=*/4, DlBlendMode::kModulate,
81 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
82
83 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
84}
85
86TEST_P(AiksTest, DrawAtlasWithColorSimple) {
87 DisplayListBuilder builder;
88 // Draws the image as four squares stiched together.
89 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
90
91 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
93
94 builder.Scale(GetContentScale().x, GetContentScale().y);
95 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
96 colors.data(), /*count=*/4, DlBlendMode::kSrcATop,
97 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
98
99 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
100}
101
102TEST_P(AiksTest, DrawAtlasWithOpacity) {
103 DisplayListBuilder builder;
104 // Draws the image as four squares stiched together slightly
105 // opaque
106 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
107
108 DlPaint paint;
109 paint.setAlpha(128);
110 builder.Scale(GetContentScale().x, GetContentScale().y);
111 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
112 /*colors=*/nullptr, 4, DlBlendMode::kSrcOver,
113 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr,
114 &paint);
115
116 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
117}
118
119TEST_P(AiksTest, DrawAtlasNoColorFullSize) {
120 auto atlas = DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
121 auto size = atlas->impeller_texture()->GetSize();
122 std::vector<DlRect> texture_coordinates = {
123 DlRect::MakeLTRB(0, 0, size.width, size.height)};
124 std::vector<RSTransform> transforms = {MakeTranslation(0, 0)};
125
126 DisplayListBuilder builder;
127 builder.Scale(GetContentScale().x, GetContentScale().y);
128 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
129 /*colors=*/nullptr, /*count=*/1, DlBlendMode::kSrcOver,
130 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
131
132 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
133}
134
135// Regression test for https://github.com/flutter/flutter/issues/127374.
136TEST_P(AiksTest, DrawAtlasAdvancedAndTransform) {
137 DisplayListBuilder builder;
138 // Draws the image as four squares stiched together.
139 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
140
141 builder.Scale(0.25, 0.25);
142 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
143 /*colors=*/nullptr, /*count=*/4, DlBlendMode::kModulate,
144 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
145
146 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
147}
148
149// Regression test for https://github.com/flutter/flutter/issues/127374.
150TEST_P(AiksTest, DrawAtlasWithColorAdvancedAndTransform) {
151 DisplayListBuilder builder;
152 // Draws the image as four squares stiched together.
153 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
154 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
156
157 builder.Scale(0.25, 0.25);
158 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
159 colors.data(), /*count=*/4, DlBlendMode::kModulate,
160 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
161
162 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
163}
164
165TEST_P(AiksTest, DrawAtlasPlusWideGamut) {
166 DisplayListBuilder builder;
167 EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
169
170 // Draws the image as four squares stiched together.
171 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
172 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
174
175 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
176 colors.data(), /*count=*/4, DlBlendMode::kPlus,
177 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
178
179 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
180}
181
182TEST_P(AiksTest, DlAtlasGeometryNoBlendRenamed) {
183 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
184
185 DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
186 texture_coordinates.data(), nullptr, transforms.size(),
187 BlendMode::kSrcOver, {}, std::nullopt);
188
189 EXPECT_FALSE(geom.ShouldUseBlend());
190 EXPECT_FALSE(geom.ShouldSkip());
191
192 ContentContext context(GetContext(), nullptr);
193 auto vertex_buffer =
195
196 EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
197 EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
198}
199
200TEST_P(AiksTest, DlAtlasGeometryBlend) {
201 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
202
203 std::vector<DlColor> colors;
204 colors.reserve(texture_coordinates.size());
205 for (auto i = 0u; i < texture_coordinates.size(); i++) {
206 colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
207 }
208 DlAtlasGeometry geom(
209 atlas->impeller_texture(), transforms.data(), texture_coordinates.data(),
210 colors.data(), transforms.size(), BlendMode::kSrcOver, {}, std::nullopt);
211
212 EXPECT_TRUE(geom.ShouldUseBlend());
213 EXPECT_FALSE(geom.ShouldSkip());
214
215 ContentContext context(GetContext(), nullptr);
216 auto vertex_buffer =
218
219 EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
220 EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
221}
222
223TEST_P(AiksTest, DlAtlasGeometryColorButNoBlend) {
224 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
225
226 std::vector<DlColor> colors;
227 colors.reserve(texture_coordinates.size());
228 for (auto i = 0u; i < texture_coordinates.size(); i++) {
229 colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
230 }
231 DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
232 texture_coordinates.data(), colors.data(),
233 transforms.size(), BlendMode::kSrc, {}, std::nullopt);
234
235 // Src blend mode means that colors would be ignored, even if provided.
236 EXPECT_FALSE(geom.ShouldUseBlend());
237 EXPECT_FALSE(geom.ShouldSkip());
238}
239
240TEST_P(AiksTest, DlAtlasGeometrySkip) {
241 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
242
243 std::vector<DlColor> colors;
244 colors.reserve(texture_coordinates.size());
245 for (auto i = 0u; i < texture_coordinates.size(); i++) {
246 colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
247 }
248 DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
249 texture_coordinates.data(), colors.data(),
250 transforms.size(), BlendMode::kClear, {}, std::nullopt);
251 EXPECT_TRUE(geom.ShouldSkip());
252}
253
254TEST_P(AiksTest, DrawImageRectWithBlendColorFilter) {
255 sk_sp<DlImageImpeller> texture =
256 DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
257
258 DisplayListBuilder builder;
260 DlColor::kRed().withAlphaF(0.4), DlBlendMode::kSrcOver));
261
262 DlMatrix filter_matrix = DlMatrix();
263 auto filter = flutter::DlMatrixImageFilter(filter_matrix,
265 DlPaint paint_with_filter = paint;
266 paint_with_filter.setImageFilter(&filter);
267
268 // Compare porter-duff blend modes.
269 builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
270 // Uses image filter to disable atlas conversion.
271 builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
272 DlRect::MakeLTRB(0, 0, 500, 500), {},
273 &paint_with_filter);
274
275 // Uses atlas conversion.
276 builder.Translate(600, 0);
277 builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
278 DlRect::MakeLTRB(0, 0, 500, 500), {}, &paint);
279
280 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
281}
282
283TEST_P(AiksTest, DrawImageRectWithMatrixColorFilter) {
284 sk_sp<DlImageImpeller> texture =
285 DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
286
287 DisplayListBuilder builder;
288 static const constexpr ColorMatrix kColorInversion = {
289 .array = {
290 -1.0, 0, 0, 1.0, 0, //
291 0, -1.0, 0, 1.0, 0, //
292 0, 0, -1.0, 1.0, 0, //
293 1.0, 1.0, 1.0, 1.0, 0 //
294 }};
297
298 DlMatrix filter_matrix = DlMatrix();
299 auto filter = flutter::DlMatrixImageFilter(filter_matrix,
301 DlPaint paint_with_filter = paint;
302 paint_with_filter.setImageFilter(&filter);
303
304 // Compare inverting color matrix filter.
305 builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
306 // Uses image filter to disable atlas conversion.
307 builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
308 DlRect::MakeLTRB(0, 0, 500, 500), {},
309 &paint_with_filter);
310
311 // Uses atlas conversion.
312 builder.Translate(600, 0);
313 builder.DrawImageRect(texture, DlRect::MakeSize(texture->GetSize()),
314 DlRect::MakeLTRB(0, 0, 500, 500), {}, &paint);
315
316 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
317}
318
319TEST_P(AiksTest, DrawAtlasWithColorBurn) {
320 DisplayListBuilder builder;
321 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
322
323 std::vector<DlColor> colors = {DlColor::kDarkGrey(), DlColor::kBlack(),
325
326 builder.Scale(GetContentScale().x, GetContentScale().y);
327 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
328 colors.data(), /*count=*/4, DlBlendMode::kColorBurn,
329 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
330
331 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
332}
333
334} // namespace testing
335} // 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()
Definition dl_builder.cc:66
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
HostBuffer & GetTransientsDataBuffer() const
Retrieve the current host buffer for transient storage of other non-index data.
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.
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