5 #include "flutter/testing/testing.h"
6 #include "fml/status_or.h"
7 #include "gmock/gmock.h"
12 #include "impeller/renderer/testing/mocks.h"
22 float LowerBoundNewtonianMethod(
const std::function<
float(
float)>& func,
26 const float delta = 1e-6;
31 fx = func(x) - target;
32 float derivative = (func(x + delta) - func(x)) / delta;
33 x = x - fx / derivative;
35 }
while (std::abs(fx) > tolerance ||
48 return LowerBoundNewtonianMethod(f, radius, 2.f, 0.001f);
58 ->GetResourceAllocator()
59 ->CreateTexture(desc);
76 std::optional<Rect> coverage =
78 ASSERT_FALSE(coverage.has_value());
87 std::optional<Rect> coverage =
93 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
100 std::optional<Rect> coverage =
102 EXPECT_TRUE(coverage.has_value());
103 if (coverage.has_value()) {
112 .size =
ISize(100, 100),
114 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
118 std::shared_ptr<Texture> texture =
119 GetContentContext()->GetContext()->GetResourceAllocator()->CreateTexture(
124 std::optional<Rect> coverage =
126 EXPECT_TRUE(coverage.has_value());
127 if (coverage.has_value()) {
136 .size =
ISize(100, 100),
138 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
142 std::shared_ptr<Texture> texture =
143 GetContentContext()->GetContext()->GetResourceAllocator()->CreateTexture(
150 EXPECT_TRUE(coverage.has_value());
151 if (coverage.has_value()) {
158 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
159 auto contents = std::make_unique<GaussianBlurFilterContents>(
161 std::optional<Rect> coverage = contents->GetFilterSourceCoverage(
164 ASSERT_EQ(coverage,
Rect::MakeLTRB(100 - 2, 100 - 2, 200 + 2, 200 + 2));
180 .size =
ISize(100, 100),
182 std::shared_ptr<Texture> texture = MakeTexture(desc);
183 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
184 auto contents = std::make_unique<GaussianBlurFilterContents>(
187 std::shared_ptr<ContentContext> renderer = GetContentContext();
190 std::optional<Entity> result =
191 contents->GetEntity(*renderer, entity, {});
192 EXPECT_TRUE(result.has_value());
193 if (result.has_value()) {
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(),
209 RenderCoverageMatchesGetCoverageTranslate) {
213 .size =
ISize(100, 100),
215 std::shared_ptr<Texture> texture = MakeTexture(desc);
216 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
217 auto contents = std::make_unique<GaussianBlurFilterContents>(
220 std::shared_ptr<ContentContext> renderer = GetContentContext();
224 std::optional<Entity> result =
225 contents->GetEntity(*renderer, entity, {});
227 EXPECT_TRUE(result.has_value());
228 if (result.has_value()) {
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(),
244 RenderCoverageMatchesGetCoverageRotated) {
248 .size =
ISize(400, 300),
250 std::shared_ptr<Texture> texture = MakeTexture(desc);
251 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
252 auto contents = std::make_unique<GaussianBlurFilterContents>(
255 std::shared_ptr<ContentContext> renderer = GetContentContext();
261 std::optional<Entity> result =
262 contents->GetEntity(*renderer, entity, {});
263 EXPECT_TRUE(result.has_value());
264 if (result.has_value()) {
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(),
283 .size =
ISize(100, 100),
285 std::shared_ptr<Texture> texture = MakeTexture(desc);
291 EXPECT_TRUE(uvs_bounds.has_value());
292 if (uvs_bounds.has_value()) {
301 .size =
ISize(100, 100),
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);
309 50, 40, texture->GetSize().width, texture->GetSize().height));
311 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
312 auto contents = std::make_unique<GaussianBlurFilterContents>(
315 std::shared_ptr<ContentContext> renderer = GetContentContext();
318 std::optional<Entity> result =
319 contents->GetEntity(*renderer, entity, {});
320 EXPECT_TRUE(result.has_value());
321 if (result.has_value()) {
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(),
336 TextureContentsWithDestinationRectScaled) {
340 .size =
ISize(100, 100),
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);
348 50, 40, texture->GetSize().width, texture->GetSize().height));
350 Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
351 auto contents = std::make_unique<GaussianBlurFilterContents>(
354 std::shared_ptr<ContentContext> renderer = GetContentContext();
358 std::optional<Entity> result =
359 contents->GetEntity(*renderer, entity, {});
360 EXPECT_TRUE(result.has_value());
361 if (result.has_value()) {
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(),
379 Scalar derived_sigma = CalculateSigmaForBlurRadius(radius);
381 EXPECT_NEAR(sigma, derived_sigma, 0.01f);
389 KernelPipeline::FragmentShader::KernelSamples samples =
391 EXPECT_EQ(samples.sample_count, 11);
395 for (
int i = 0; i < samples.sample_count; ++i) {
396 tally += samples.samples[i].coefficient;
398 EXPECT_FLOAT_EQ(tally, 1.0f);
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);