| Flutter Impeller |

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
5 #include "display_list/dl_sampling_options.h"
6 #include "flutter/impeller/display_list/aiks_unittests.h"
7
8 #include "flutter/display_list/dl_blend_mode.h"
9 #include "flutter/display_list/dl_builder.h"
10 #include "flutter/display_list/dl_color.h"
11 #include "flutter/display_list/dl_paint.h"
12 #include "flutter/testing/testing.h"
13 #include "impeller/core/formats.h"
14 #include "impeller/display_list/dl_atlas_geometry.h"
15 #include "impeller/display_list/dl_image_impeller.h"
16 #include "impeller/entity/contents/content_context.h"
17 #include "impeller/geometry/color.h"
18 #include "impeller/geometry/scalar.h"
19 #include "include/core/SkRSXform.h"
20 #include "include/core/SkRefCnt.h"
21
22 namespace impeller {
23 namespace testing {
24
25 using namespace flutter;
26
27 namespace {
28 SkRSXform MakeTranslation(Scalar tx, Scalar ty) {
29 return SkRSXform::Make(1, 0, tx, ty);
30 }
31
32 std::tuple<std::vector<SkRect>, std::vector<SkRSXform>, sk_sp<DlImageImpeller>>
33 CreateTestData(const AiksTest* test) {
34 // Draws the image as four squares stiched together.
35 auto atlas =
36 DlImageImpeller::Make(test->CreateTextureForFixture("bay_bridge.jpg"));
37 auto size = atlas->impeller_texture()->GetSize();
38 // Divide image into four quadrants.
39 Scalar half_width = size.width / 2;
40 Scalar half_height = size.height / 2;
41 std::vector<SkRect> texture_coordinates = {
42 SkRect::MakeLTRB(0, 0, half_width, half_height),
43 SkRect::MakeLTRB(half_width, 0, size.width, half_height),
44 SkRect::MakeLTRB(0, half_height, half_width, size.height),
45 SkRect::MakeLTRB(half_width, half_height, size.width, size.height)};
46 // Position quadrants adjacent to eachother.
47 std::vector<SkRSXform> transforms = {
48 MakeTranslation(0, 0), MakeTranslation(half_width, 0),
49 MakeTranslation(0, half_height),
50 MakeTranslation(half_width, half_height)};
51 return std::make_tuple(texture_coordinates, transforms, atlas);
52 }
53
54 std::tuple<std::vector<DlRect>, std::vector<SkRSXform>, sk_sp<DlImageImpeller>>
55 CreateDlTestData(const AiksTest* test) {
56 // Draws the image as four squares stiched together.
57 auto atlas =
58 DlImageImpeller::Make(test->CreateTextureForFixture("bay_bridge.jpg"));
59 auto size = atlas->impeller_texture()->GetSize();
60 // Divide image into four quadrants.
61 Scalar half_width = size.width / 2;
62 Scalar half_height = size.height / 2;
63 std::vector<DlRect> texture_coordinates = {
64 DlRect::MakeLTRB(0, 0, half_width, half_height),
65 DlRect::MakeLTRB(half_width, 0, size.width, half_height),
66 DlRect::MakeLTRB(0, half_height, half_width, size.height),
67 DlRect::MakeLTRB(half_width, half_height, size.width, size.height)};
68 // Position quadrants adjacent to eachother.
69 std::vector<SkRSXform> transforms = {
70 MakeTranslation(0, 0), MakeTranslation(half_width, 0),
71 MakeTranslation(0, half_height),
72 MakeTranslation(half_width, half_height)};
73 return std::make_tuple(texture_coordinates, transforms, atlas);
74 }
75
76 } // namespace
77
78 TEST_P(AiksTest, DrawAtlasNoColor) {
79 DisplayListBuilder builder;
80 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
81
82 builder.Scale(GetContentScale().x, GetContentScale().y);
83 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
84 /*colors=*/nullptr, /*count=*/4, DlBlendMode::kSrcOver,
85 DlImageSampling::kNearestNeighbor, nullptr);
86
87 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
88 }
89
90 TEST_P(AiksTest, DrawAtlasWithColorAdvanced) {
91 DisplayListBuilder builder;
92 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
93
94 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
95 DlColor::kBlue(), DlColor::kYellow()};
96
97 builder.Scale(GetContentScale().x, GetContentScale().y);
98 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
99 colors.data(), /*count=*/4, DlBlendMode::kModulate,
100 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
101
102 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
103 }
104
105 TEST_P(AiksTest, DrawAtlasWithColorSimple) {
106 DisplayListBuilder builder;
107 // Draws the image as four squares stiched together.
108 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
109
110 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
111 DlColor::kBlue(), DlColor::kYellow()};
112
113 builder.Scale(GetContentScale().x, GetContentScale().y);
114 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
115 colors.data(), /*count=*/4, DlBlendMode::kSrcATop,
116 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
117
118 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
119 }
120
121 TEST_P(AiksTest, DrawAtlasWithOpacity) {
122 DisplayListBuilder builder;
123 // Draws the image as four squares stiched together slightly
124 // opaque
125 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
126
127 DlPaint paint;
128 paint.setAlpha(128);
129 builder.Scale(GetContentScale().x, GetContentScale().y);
130 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
131 /*colors=*/nullptr, 4, DlBlendMode::kSrcOver,
132 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr,
133 &paint);
134
135 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
136 }
137
138 TEST_P(AiksTest, DrawAtlasNoColorFullSize) {
139 auto atlas = DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
140 auto size = atlas->impeller_texture()->GetSize();
141 std::vector<SkRect> texture_coordinates = {
142 SkRect::MakeLTRB(0, 0, size.width, size.height)};
143 std::vector<SkRSXform> transforms = {MakeTranslation(0, 0)};
144
145 DisplayListBuilder builder;
146 builder.Scale(GetContentScale().x, GetContentScale().y);
147 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
148 /*colors=*/nullptr, /*count=*/1, DlBlendMode::kSrcOver,
149 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
150
151 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
152 }
153
154 // Regression test for https://github.com/flutter/flutter/issues/127374.
155 TEST_P(AiksTest, DrawAtlasAdvancedAndTransform) {
156 DisplayListBuilder builder;
157 // Draws the image as four squares stiched together.
158 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
159
160 builder.Scale(0.25, 0.25);
161 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
162 /*colors=*/nullptr, /*count=*/4, DlBlendMode::kModulate,
163 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
164
165 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
166 }
167
168 // Regression test for https://github.com/flutter/flutter/issues/127374.
169 TEST_P(AiksTest, DrawAtlasWithColorAdvancedAndTransform) {
170 DisplayListBuilder builder;
171 // Draws the image as four squares stiched together.
172 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
173 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
174 DlColor::kBlue(), DlColor::kYellow()};
175
176 builder.Scale(0.25, 0.25);
177 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
178 colors.data(), /*count=*/4, DlBlendMode::kModulate,
179 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
180
181 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
182 }
183
184 TEST_P(AiksTest, DrawAtlasPlusWideGamut) {
185 DisplayListBuilder builder;
186 EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
187 PixelFormat::kB10G10R10A10XR);
188
189 // Draws the image as four squares stiched together.
190 auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
191 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
192 DlColor::kBlue(), DlColor::kYellow()};
193
194 builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
195 colors.data(), /*count=*/4, DlBlendMode::kPlus,
196 DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
197
198 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
199 }
200
201 TEST_P(AiksTest, DlAtlasGeometryNoBlend) {
202 auto [texture_coordinates, transforms, atlas] = CreateDlTestData(this);
203
204 DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
205 texture_coordinates.data(), nullptr, transforms.size(),
206 BlendMode::kSourceOver, {}, std::nullopt);
207
208 EXPECT_FALSE(geom.ShouldUseBlend());
209 EXPECT_FALSE(geom.ShouldSkip());
210
211 ContentContext context(GetContext(), nullptr);
212 auto vertex_buffer =
213 geom.CreateSimpleVertexBuffer(context.GetTransientsBuffer());
214
215 EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
216 EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
217 }
218
219 TEST_P(AiksTest, DlAtlasGeometryBlend) {
220 auto [texture_coordinates, transforms, atlas] = CreateDlTestData(this);
221
222 std::vector<DlColor> colors;
223 colors.reserve(texture_coordinates.size());
224 for (auto i = 0u; i < texture_coordinates.size(); i++) {
225 colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
226 }
227 DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
228 texture_coordinates.data(), colors.data(),
229 transforms.size(), BlendMode::kSourceOver, {},
230 std::nullopt);
231
232 EXPECT_TRUE(geom.ShouldUseBlend());
233 EXPECT_FALSE(geom.ShouldSkip());
234
235 ContentContext context(GetContext(), nullptr);
236 auto vertex_buffer =
237 geom.CreateBlendVertexBuffer(context.GetTransientsBuffer());
238
239 EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
240 EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
241 }
242
243 TEST_P(AiksTest, DlAtlasGeometryColorButNoBlend) {
244 auto [texture_coordinates, transforms, atlas] = CreateDlTestData(this);
245
246 std::vector<DlColor> colors;
247 colors.reserve(texture_coordinates.size());
248 for (auto i = 0u; i < texture_coordinates.size(); i++) {
249 colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
250 }
251 DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
252 texture_coordinates.data(), colors.data(),
253 transforms.size(), BlendMode::kSource, {}, std::nullopt);
254
255 // Src blend mode means that colors would be ignored, even if provided.
256 EXPECT_FALSE(geom.ShouldUseBlend());
257 EXPECT_FALSE(geom.ShouldSkip());
258 }
259
260 TEST_P(AiksTest, DlAtlasGeometrySkip) {
261 auto [texture_coordinates, transforms, atlas] = CreateDlTestData(this);
262
263 std::vector<DlColor> colors;
264 colors.reserve(texture_coordinates.size());
265 for (auto i = 0u; i < texture_coordinates.size(); i++) {
266 colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
267 }
268 DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
269 texture_coordinates.data(), colors.data(),
270 transforms.size(), BlendMode::kClear, {}, std::nullopt);
271 EXPECT_TRUE(geom.ShouldSkip());
272 }
273
274 } // namespace testing
275 } // namespace impeller
impeller::AiksPlayground
Definition: aiks_playground.h:16
impeller::DlAtlasGeometry::CreateSimpleVertexBuffer
VertexBuffer CreateSimpleVertexBuffer(HostBuffer &host_buffer) const override
Definition: dl_atlas_geometry.cc:72
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::PixelFormat::kB10G10R10A10XR
@ kB10G10R10A10XR
aiks_unittests.h
impeller::DlAtlasGeometry::CreateBlendVertexBuffer
VertexBuffer CreateBlendVertexBuffer(HostBuffer &host_buffer) const override
Definition: dl_atlas_geometry.cc:107
impeller::testing::AiksTest
AiksPlayground AiksTest
Definition: aiks_unittests.h:17
impeller::BlendMode::kSource
@ kSource
formats.h
impeller::DlImageImpeller::Make
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
Definition: dl_image_impeller.cc:23
impeller::DlAtlasGeometry
A wrapper around data provided by a drawAtlas call.
Definition: dl_atlas_geometry.h:18
impeller::BlendMode::kClear
@ kClear
impeller::IndexType::kNone
@ kNone
Does not use the index buffer.
flutter
Definition: dl_golden_blur_unittests.cc:15
dl_atlas_geometry.h
impeller::testing::TEST_P
TEST_P(AiksTest, DrawAtlasNoColor)
Definition: aiks_dl_atlas_unittests.cc:78
scalar.h
content_context.h
impeller::DlAtlasGeometry::ShouldSkip
bool ShouldSkip() const override
Definition: dl_atlas_geometry.cc:41
impeller::DlAtlasGeometry::ShouldUseBlend
bool ShouldUseBlend() const override
Whether the blend shader should be used.
Definition: dl_atlas_geometry.cc:37
color.h
impeller
Definition: allocation.cc:12
impeller::ContentContext
Definition: content_context.h:366
impeller::BlendMode::kSourceOver
@ kSourceOver
impeller::ContentContext::GetTransientsBuffer
HostBuffer & GetTransientsBuffer() const
Retrieve the currnent host buffer for transient storage.
Definition: content_context.h:753
dl_image_impeller.h