| Flutter Impeller |

gaussian_blur_filter_contents_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 "flutter/testing/testing.h"
6 #include "fml/status_or.h"
7 #include "gmock/gmock.h"
8 #include "impeller/entity/contents/filters/gaussian_blur_filter_contents.h"
9 #include "impeller/entity/contents/texture_contents.h"
10 #include "impeller/entity/entity_playground.h"
11 #include "impeller/geometry/geometry_asserts.h"
12 #include "impeller/renderer/testing/mocks.h"
13
14 namespace impeller {
15 namespace testing {
16
17 namespace {
18
19 // Use newtonian method to give the closest answer to target where
20 // f(x) is less than the target. We do this because the value is `ceil`'d to
21 // grab fractional pixels.
22 float LowerBoundNewtonianMethod(const std::function<float(float)>& func,
23 float target,
24 float guess,
25 float tolerance) {
26 const float delta = 1e-6;
27 float x = guess;
28 float fx;
29
30 do {
31 fx = func(x) - target;
32 float derivative = (func(x + delta) - func(x)) / delta;
33 x = x - fx / derivative;
34
35 } while (std::abs(fx) > tolerance ||
36 fx < 0.0); // fx < 0.0 makes this lower bound.
37
38 return x;
39 }
40
41 Scalar CalculateSigmaForBlurRadius(Scalar radius) {
42 auto f = [](Scalar x) -> Scalar {
43 return GaussianBlurFilterContents::CalculateBlurRadius(
44 GaussianBlurFilterContents::ScaleSigma(x));
45 };
46 // The newtonian method is used here since inverting the function is
47 // non-trivial because of conditional logic and would be fragile to changes.
48 return LowerBoundNewtonianMethod(f, radius, 2.f, 0.001f);
49 }
50
51 } // namespace
52
53 class GaussianBlurFilterContentsTest : public EntityPlayground {
54 public:
55 std::shared_ptr<Texture> MakeTexture(const TextureDescriptor& desc) {
56 return GetContentContext()
57 ->GetContext()
58 ->GetResourceAllocator()
59 ->CreateTexture(desc);
60 }
61 };
62 INSTANTIATE_PLAYGROUND_SUITE(GaussianBlurFilterContentsTest);
63
64 TEST(GaussianBlurFilterContentsTest, Create) {
65 GaussianBlurFilterContents contents(/*sigma_x=*/0.0, /*sigma_y=*/0.0,
66 Entity::TileMode::kDecal);
67 EXPECT_EQ(contents.GetSigmaX(), 0.0);
68 EXPECT_EQ(contents.GetSigmaY(), 0.0);
69 }
70
71 TEST(GaussianBlurFilterContentsTest, CoverageEmpty) {
72 GaussianBlurFilterContents contents(/*sigma_x=*/0.0, /*sigma_y=*/0.0,
73 Entity::TileMode::kDecal);
74 FilterInput::Vector inputs = {};
75 Entity entity;
76 std::optional<Rect> coverage =
77 contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
78 ASSERT_FALSE(coverage.has_value());
79 }
80
81 TEST(GaussianBlurFilterContentsTest, CoverageSimple) {
82 GaussianBlurFilterContents contents(/*sigma_x=*/0.0, /*sigma_y=*/0.0,
83 Entity::TileMode::kDecal);
84 FilterInput::Vector inputs = {
85 FilterInput::Make(Rect::MakeLTRB(10, 10, 110, 110))};
86 Entity entity;
87 std::optional<Rect> coverage =
88 contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
89 ASSERT_EQ(coverage, Rect::MakeLTRB(10, 10, 110, 110));
90 }
91
92 TEST(GaussianBlurFilterContentsTest, CoverageWithSigma) {
93 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
94 GaussianBlurFilterContents contents(/*sigma_x=*/sigma_radius_1,
95 /*sigma_y=*/sigma_radius_1,
96 Entity::TileMode::kDecal);
97 FilterInput::Vector inputs = {
98 FilterInput::Make(Rect::MakeLTRB(100, 100, 200, 200))};
99 Entity entity;
100 std::optional<Rect> coverage =
101 contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
102 EXPECT_TRUE(coverage.has_value());
103 if (coverage.has_value()) {
104 EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(99, 99, 201, 201));
105 }
106 }
107
108 TEST_P(GaussianBlurFilterContentsTest, CoverageWithTexture) {
109 TextureDescriptor desc = {
110 .storage_mode = StorageMode::kDevicePrivate,
111 .format = PixelFormat::kB8G8R8A8UNormInt,
112 .size = ISize(100, 100),
113 };
114 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
115 GaussianBlurFilterContents contents(/*sigma_X=*/sigma_radius_1,
116 /*sigma_y=*/sigma_radius_1,
117 Entity::TileMode::kDecal);
118 std::shared_ptr<Texture> texture =
119 GetContentContext()->GetContext()->GetResourceAllocator()->CreateTexture(
120 desc);
121 FilterInput::Vector inputs = {FilterInput::Make(texture)};
122 Entity entity;
123 entity.SetTransform(Matrix::MakeTranslation({100, 100, 0}));
124 std::optional<Rect> coverage =
125 contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
126 EXPECT_TRUE(coverage.has_value());
127 if (coverage.has_value()) {
128 EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(99, 99, 201, 201));
129 }
130 }
131
132 TEST_P(GaussianBlurFilterContentsTest, CoverageWithEffectTransform) {
133 TextureDescriptor desc = {
134 .storage_mode = StorageMode::kDevicePrivate,
135 .format = PixelFormat::kB8G8R8A8UNormInt,
136 .size = ISize(100, 100),
137 };
138 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
139 GaussianBlurFilterContents contents(/*sigma_x=*/sigma_radius_1,
140 /*sigma_y=*/sigma_radius_1,
141 Entity::TileMode::kDecal);
142 std::shared_ptr<Texture> texture =
143 GetContentContext()->GetContext()->GetResourceAllocator()->CreateTexture(
144 desc);
145 FilterInput::Vector inputs = {FilterInput::Make(texture)};
146 Entity entity;
147 entity.SetTransform(Matrix::MakeTranslation({100, 100, 0}));
148 std::optional<Rect> coverage = contents.GetFilterCoverage(
149 inputs, entity, /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0}));
150 EXPECT_TRUE(coverage.has_value());
151 if (coverage.has_value()) {
152 EXPECT_RECT_NEAR(coverage.value(),
153 Rect::MakeLTRB(100 - 2, 100 - 2, 200 + 2, 200 + 2));
154 }
155 }
156
157 TEST(GaussianBlurFilterContentsTest, FilterSourceCoverage) {
158 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
159 auto contents = std::make_unique<GaussianBlurFilterContents>(
160 sigma_radius_1, sigma_radius_1, Entity::TileMode::kDecal);
161 std::optional<Rect> coverage = contents->GetFilterSourceCoverage(
162 /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0}),
163 /*output_limit=*/Rect::MakeLTRB(100, 100, 200, 200));
164 ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100 - 2, 200 + 2, 200 + 2));
165 }
166
167 TEST(GaussianBlurFilterContentsTest, CalculateSigmaValues) {
168 EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(1.0f), 1);
169 EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(2.0f), 1);
170 EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(3.0f), 1);
171 EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(4.0f), 1);
172 EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(16.0f), 0.25);
173 EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(1024.0f), 4.f / 1024.f);
174 }
175
176 TEST_P(GaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverage) {
177 TextureDescriptor desc = {
178 .storage_mode = StorageMode::kDevicePrivate,
179 .format = PixelFormat::kB8G8R8A8UNormInt,
180 .size = ISize(100, 100),
181 };
182 std::shared_ptr<Texture> texture = MakeTexture(desc);
183 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
184 auto contents = std::make_unique<GaussianBlurFilterContents>(
185 sigma_radius_1, sigma_radius_1, Entity::TileMode::kDecal);
186 contents->SetInputs({FilterInput::Make(texture)});
187 std::shared_ptr<ContentContext> renderer = GetContentContext();
188
189 Entity entity;
190 std::optional<Entity> result =
191 contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
192 EXPECT_TRUE(result.has_value());
193 if (result.has_value()) {
194 EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
195 std::optional<Rect> result_coverage = result.value().GetCoverage();
196 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
197 EXPECT_TRUE(result_coverage.has_value());
198 EXPECT_TRUE(contents_coverage.has_value());
199 if (result_coverage.has_value() && contents_coverage.has_value()) {
200 EXPECT_TRUE(RectNear(contents_coverage.value(),
201 Rect::MakeLTRB(-1, -1, 101, 101)));
202 EXPECT_TRUE(
203 RectNear(result_coverage.value(), Rect::MakeLTRB(-1, -1, 101, 101)));
204 }
205 }
206 }
207
208 TEST_P(GaussianBlurFilterContentsTest,
209 RenderCoverageMatchesGetCoverageTranslate) {
210 TextureDescriptor desc = {
211 .storage_mode = StorageMode::kDevicePrivate,
212 .format = PixelFormat::kB8G8R8A8UNormInt,
213 .size = ISize(100, 100),
214 };
215 std::shared_ptr<Texture> texture = MakeTexture(desc);
216 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
217 auto contents = std::make_unique<GaussianBlurFilterContents>(
218 sigma_radius_1, sigma_radius_1, Entity::TileMode::kDecal);
219 contents->SetInputs({FilterInput::Make(texture)});
220 std::shared_ptr<ContentContext> renderer = GetContentContext();
221
222 Entity entity;
223 entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
224 std::optional<Entity> result =
225 contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
226
227 EXPECT_TRUE(result.has_value());
228 if (result.has_value()) {
229 EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
230 std::optional<Rect> result_coverage = result.value().GetCoverage();
231 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
232 EXPECT_TRUE(result_coverage.has_value());
233 EXPECT_TRUE(contents_coverage.has_value());
234 if (result_coverage.has_value() && contents_coverage.has_value()) {
235 EXPECT_TRUE(RectNear(contents_coverage.value(),
236 Rect::MakeLTRB(99, 199, 201, 301)));
237 EXPECT_TRUE(
238 RectNear(result_coverage.value(), Rect::MakeLTRB(99, 199, 201, 301)));
239 }
240 }
241 }
242
243 TEST_P(GaussianBlurFilterContentsTest,
244 RenderCoverageMatchesGetCoverageRotated) {
245 TextureDescriptor desc = {
246 .storage_mode = StorageMode::kDevicePrivate,
247 .format = PixelFormat::kB8G8R8A8UNormInt,
248 .size = ISize(400, 300),
249 };
250 std::shared_ptr<Texture> texture = MakeTexture(desc);
251 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
252 auto contents = std::make_unique<GaussianBlurFilterContents>(
253 sigma_radius_1, sigma_radius_1, Entity::TileMode::kDecal);
254 contents->SetInputs({FilterInput::Make(texture)});
255 std::shared_ptr<ContentContext> renderer = GetContentContext();
256
257 Entity entity;
258 // Rotate around the top left corner, then push it over to (100, 100).
259 entity.SetTransform(Matrix::MakeTranslation({400, 100, 0}) *
260 Matrix::MakeRotationZ(Degrees(90.0)));
261 std::optional<Entity> result =
262 contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
263 EXPECT_TRUE(result.has_value());
264 if (result.has_value()) {
265 EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
266 std::optional<Rect> result_coverage = result.value().GetCoverage();
267 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
268 EXPECT_TRUE(result_coverage.has_value());
269 EXPECT_TRUE(contents_coverage.has_value());
270 if (result_coverage.has_value() && contents_coverage.has_value()) {
271 EXPECT_TRUE(RectNear(contents_coverage.value(),
272 Rect::MakeLTRB(99, 99, 401, 501)));
273 EXPECT_TRUE(
274 RectNear(result_coverage.value(), Rect::MakeLTRB(99, 99, 401, 501)));
275 }
276 }
277 }
278
279 TEST_P(GaussianBlurFilterContentsTest, CalculateUVsSimple) {
280 TextureDescriptor desc = {
281 .storage_mode = StorageMode::kDevicePrivate,
282 .format = PixelFormat::kB8G8R8A8UNormInt,
283 .size = ISize(100, 100),
284 };
285 std::shared_ptr<Texture> texture = MakeTexture(desc);
286 auto filter_input = FilterInput::Make(texture);
287 Entity entity;
288 Quad uvs = GaussianBlurFilterContents::CalculateUVs(
289 filter_input, entity, Rect::MakeSize(ISize(100, 100)), ISize(100, 100));
290 std::optional<Rect> uvs_bounds = Rect::MakePointBounds(uvs);
291 EXPECT_TRUE(uvs_bounds.has_value());
292 if (uvs_bounds.has_value()) {
293 EXPECT_TRUE(RectNear(uvs_bounds.value(), Rect::MakeXYWH(0, 0, 1, 1)));
294 }
295 }
296
297 TEST_P(GaussianBlurFilterContentsTest, TextureContentsWithDestinationRect) {
298 TextureDescriptor desc = {
299 .storage_mode = StorageMode::kDevicePrivate,
300 .format = PixelFormat::kB8G8R8A8UNormInt,
301 .size = ISize(100, 100),
302 };
303
304 std::shared_ptr<Texture> texture = MakeTexture(desc);
305 auto texture_contents = std::make_shared<TextureContents>();
306 texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
307 texture_contents->SetTexture(texture);
308 texture_contents->SetDestinationRect(Rect::MakeXYWH(
309 50, 40, texture->GetSize().width, texture->GetSize().height));
310
311 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
312 auto contents = std::make_unique<GaussianBlurFilterContents>(
313 sigma_radius_1, sigma_radius_1, Entity::TileMode::kDecal);
314 contents->SetInputs({FilterInput::Make(texture_contents)});
315 std::shared_ptr<ContentContext> renderer = GetContentContext();
316
317 Entity entity;
318 std::optional<Entity> result =
319 contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
320 EXPECT_TRUE(result.has_value());
321 if (result.has_value()) {
322 EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
323 std::optional<Rect> result_coverage = result.value().GetCoverage();
324 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
325 EXPECT_TRUE(result_coverage.has_value());
326 EXPECT_TRUE(contents_coverage.has_value());
327 if (result_coverage.has_value() && contents_coverage.has_value()) {
328 EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
329 EXPECT_TRUE(RectNear(result_coverage.value(),
330 Rect::MakeLTRB(49.f, 39.f, 151.f, 141.f)));
331 }
332 }
333 }
334
335 TEST_P(GaussianBlurFilterContentsTest,
336 TextureContentsWithDestinationRectScaled) {
337 TextureDescriptor desc = {
338 .storage_mode = StorageMode::kDevicePrivate,
339 .format = PixelFormat::kB8G8R8A8UNormInt,
340 .size = ISize(100, 100),
341 };
342
343 std::shared_ptr<Texture> texture = MakeTexture(desc);
344 auto texture_contents = std::make_shared<TextureContents>();
345 texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
346 texture_contents->SetTexture(texture);
347 texture_contents->SetDestinationRect(Rect::MakeXYWH(
348 50, 40, texture->GetSize().width, texture->GetSize().height));
349
350 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
351 auto contents = std::make_unique<GaussianBlurFilterContents>(
352 sigma_radius_1, sigma_radius_1, Entity::TileMode::kDecal);
353 contents->SetInputs({FilterInput::Make(texture_contents)});
354 std::shared_ptr<ContentContext> renderer = GetContentContext();
355
356 Entity entity;
357 entity.SetTransform(Matrix::MakeScale({2.0, 2.0, 1.0}));
358 std::optional<Entity> result =
359 contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
360 EXPECT_TRUE(result.has_value());
361 if (result.has_value()) {
362 EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
363 std::optional<Rect> result_coverage = result.value().GetCoverage();
364 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
365 EXPECT_TRUE(result_coverage.has_value());
366 EXPECT_TRUE(contents_coverage.has_value());
367 if (result_coverage.has_value() && contents_coverage.has_value()) {
368 EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
369 EXPECT_TRUE(RectNear(contents_coverage.value(),
370 Rect::MakeLTRB(98.f, 78.f, 302.f, 282.f)));
371 }
372 }
373 }
374
375 TEST(GaussianBlurFilterContentsTest, CalculateSigmaForBlurRadius) {
376 Scalar sigma = 1.0;
377 Scalar radius = GaussianBlurFilterContents::CalculateBlurRadius(
378 GaussianBlurFilterContents::ScaleSigma(sigma));
379 Scalar derived_sigma = CalculateSigmaForBlurRadius(radius);
380
381 EXPECT_NEAR(sigma, derived_sigma, 0.01f);
382 }
383
384 TEST(GaussianBlurFilterContentsTest, Coefficients) {
385 BlurParameters parameters = {.blur_uv_offset = Point(1, 0),
386 .blur_sigma = 1,
387 .blur_radius = 5,
388 .step_size = 1};
389 KernelPipeline::FragmentShader::KernelSamples samples =
390 GenerateBlurInfo(parameters);
391 EXPECT_EQ(samples.sample_count, 11);
392
393 // Coefficients should add up to 1.
394 Scalar tally = 0;
395 for (int i = 0; i < samples.sample_count; ++i) {
396 tally += samples.samples[i].coefficient;
397 }
398 EXPECT_FLOAT_EQ(tally, 1.0f);
399
400 // Verify the shape of the curve.
401 for (int i = 0; i < 5; ++i) {
402 EXPECT_FLOAT_EQ(samples.samples[i].coefficient,
403 samples.samples[10 - i].coefficient);
404 EXPECT_TRUE(samples.samples[i + 1].coefficient >
405 samples.samples[i].coefficient);
406 }
407 }
408
409 } // namespace testing
410 } // namespace impeller
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::testing::GaussianBlurFilterContentsTest::MakeTexture
std::shared_ptr< Texture > MakeTexture(const TextureDescriptor &desc)
Definition: gaussian_blur_filter_contents_unittests.cc:55
texture_contents.h
geometry_asserts.h
impeller::BlurParameters::blur_uv_offset
Point blur_uv_offset
Definition: gaussian_blur_filter_contents.h:15
impeller::TRect< Scalar >::MakeXYWH
constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition: rect.h:34
impeller::FilterInput::Make
static FilterInput::Ref Make(Variant input, bool msaa_enabled=true)
Definition: filter_input.cc:19
impeller::Entity::TileMode::kDecal
@ kDecal
gaussian_blur_filter_contents.h
impeller::GaussianBlurFilterContents::CalculateBlurRadius
static Scalar CalculateBlurRadius(Scalar sigma)
Definition: gaussian_blur_filter_contents.cc:405
impeller::Matrix::MakeTranslation
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95
impeller::GenerateBlurInfo
KernelPipeline::FragmentShader::KernelSamples GenerateBlurInfo(BlurParameters parameters)
Definition: gaussian_blur_filter_contents.cc:435
EXPECT_RECT_NEAR
#define EXPECT_RECT_NEAR(a, b)
Definition: geometry_asserts.h:170
impeller::TRect< Scalar >::MakePointBounds
constexpr static std::optional< TRect > MakePointBounds(const U &value)
Definition: rect.h:49
impeller::GaussianBlurFilterContents::GetSigmaX
Scalar GetSigmaX() const
Definition: gaussian_blur_filter_contents.h:34
impeller::testing::INSTANTIATE_PLAYGROUND_SUITE
INSTANTIATE_PLAYGROUND_SUITE(AiksTest)
impeller::GaussianBlurFilterContents::GetFilterCoverage
std::optional< Rect > GetFilterCoverage(const FilterInput::Vector &inputs, const Entity &entity, const Matrix &effect_transform) const override
Internal utility method for |GetLocalCoverage| that computes the output coverage of this filter acros...
Definition: gaussian_blur_filter_contents.cc:225
impeller::Entity
Definition: entity.h:21
impeller::Point
TPoint< Scalar > Point
Definition: point.h:308
impeller::Quad
std::array< Point, 4 > Quad
Definition: point.h:313
impeller::StorageMode::kDevicePrivate
@ kDevicePrivate
impeller::testing::TEST
TEST(CanvasRecorder, Save)
Definition: canvas_recorder_unittests.cc:61
impeller::BlurParameters
Definition: gaussian_blur_filter_contents.h:14
impeller::ISize
TSize< int64_t > ISize
Definition: size.h:138
impeller::testing::GaussianBlurFilterContentsTest
Definition: gaussian_blur_filter_contents_unittests.cc:53
impeller::GaussianBlurFilterContents::GetSigmaY
Scalar GetSigmaY() const
Definition: gaussian_blur_filter_contents.h:35
impeller::EntityPlayground
Definition: entity_playground.h:18
impeller::Entity::SetTransform
void SetTransform(const Matrix &transform)
Set the global transform matrix for this Entity.
Definition: entity.cc:53
impeller::Matrix::MakeRotationZ
static Matrix MakeRotationZ(Radians r)
Definition: matrix.h:209
RectNear
inline ::testing::AssertionResult RectNear(impeller::Rect a, impeller::Rect b)
Definition: geometry_asserts.h:56
impeller::TRect< Scalar >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:44
impeller::GaussianBlurFilterContents::CalculateScale
static Scalar CalculateScale(Scalar sigma)
Definition: gaussian_blur_filter_contents.cc:207
impeller::Degrees
Definition: scalar.h:46
impeller::TextureDescriptor::storage_mode
StorageMode storage_mode
Definition: texture_descriptor.h:38
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:27
impeller::GaussianBlurFilterContents::CalculateUVs
static Quad CalculateUVs(const std::shared_ptr< FilterInput > &filter_input, const Entity &entity, const Rect &source_rect, const ISize &texture_size)
Definition: gaussian_blur_filter_contents.cc:409
impeller::TextureDescriptor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
Definition: texture_descriptor.h:37
impeller::FilterInput::Vector
std::vector< FilterInput::Ref > Vector
Definition: filter_input.h:33
impeller::testing::TEST_P
TEST_P(AiksTest, CanRenderLinearGradientClamp)
Definition: aiks_gradient_unittests.cc:48
impeller::PixelFormat::kB8G8R8A8UNormInt
@ kB8G8R8A8UNormInt
impeller::GaussianBlurFilterContents
Definition: gaussian_blur_filter_contents.h:28
impeller
Definition: aiks_context.cc:10
impeller::Matrix::MakeScale
static constexpr Matrix MakeScale(const Vector3 &s)
Definition: matrix.h:104
impeller::EntityPlayground::GetContentContext
std::shared_ptr< ContentContext > GetContentContext() const
Definition: entity_playground.cc:39
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::BlendMode::kSourceOver
@ kSourceOver
entity_playground.h
impeller::GaussianBlurFilterContents::ScaleSigma
static Scalar ScaleSigma(Scalar sigma)
Definition: gaussian_blur_filter_contents.cc:425