7#include "gmock/gmock.h"
17#define IMPELLER_RAND arc4random
19#define IMPELLER_RAND rand
31 const std::function<
float(
float)>& func,
35 const double delta = 1e-6;
38 static const int kMaxIterations = 1000;
43 double derivative = (func(
x + delta) - func(
x)) / delta;
44 x =
x - fx / derivative;
45 if (++count > kMaxIterations) {
47 "Did not converge on answer.");
49 }
while (std::abs(fx) > tolerance ||
55Scalar GetCoefficient(
const Vector4& vec) {
59Vector2 GetUVOffset(
const Vector4& vec) {
65 const Matrix& effect_transform) {
78 return LowerBoundNewtonianMethod(f, radius, 2.f, 0.001f);
87 std::shared_ptr<CommandBuffer> command_buffer =
89 if (!command_buffer) {
94 "Clear Subpass",
size, command_buffer,
100 ->Submit({command_buffer})
105 if (render_target.ok()) {
106 return render_target.value().GetRenderTargetTexture();
129 std::optional<Rect> coverage =
131 ASSERT_FALSE(coverage.has_value());
142 std::optional<Rect> coverage =
150 CalculateSigmaForBlurRadius(1.0,
Matrix());
151 ASSERT_TRUE(sigma_radius_1.
ok());
153 sigma_radius_1.
value(),
160 std::optional<Rect> coverage =
163 EXPECT_TRUE(coverage.has_value());
164 if (coverage.has_value()) {
171 CalculateSigmaForBlurRadius(1.0,
Matrix());
172 ASSERT_TRUE(sigma_radius_1.
ok());
174 sigma_radius_1.
value(),
178 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
182 std::optional<Rect> coverage =
185 EXPECT_TRUE(coverage.has_value());
186 if (coverage.has_value()) {
194 CalculateSigmaForBlurRadius(1.0, effect_transform);
195 ASSERT_TRUE(sigma_radius_1.ok());
197 sigma_radius_1.value(),
201 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
205 std::optional<Rect> coverage =
207 EXPECT_TRUE(coverage.has_value());
208 if (coverage.has_value()) {
216 CalculateSigmaForBlurRadius(1.0,
Matrix());
217 ASSERT_TRUE(sigma_radius_1.
ok());
218 auto contents = std::make_unique<GaussianBlurFilterContents>(
222 std::optional<Rect> coverage = contents->GetFilterSourceCoverage(
225 EXPECT_TRUE(coverage.has_value());
226 if (coverage.has_value()) {
246 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
248 CalculateSigmaForBlurRadius(1.0,
Matrix());
249 ASSERT_TRUE(sigma_radius_1.
ok());
250 auto contents = std::make_unique<GaussianBlurFilterContents>(
255 std::shared_ptr<ContentContext> renderer = GetContentContext();
258 std::optional<Entity> result =
259 contents->GetEntity(*renderer, entity, {});
260 EXPECT_TRUE(result.has_value());
261 if (result.has_value()) {
263 std::optional<Rect> result_coverage = result.value().GetCoverage();
264 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
265 EXPECT_TRUE(result_coverage.has_value());
266 EXPECT_TRUE(contents_coverage.has_value());
267 if (result_coverage.has_value() && contents_coverage.has_value()) {
268 EXPECT_TRUE(
RectNear(contents_coverage.value(),
277 RenderCoverageMatchesGetCoverageTranslate) {
278 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
280 CalculateSigmaForBlurRadius(1.0,
Matrix());
281 ASSERT_TRUE(sigma_radius_1.
ok());
282 auto contents = std::make_unique<GaussianBlurFilterContents>(
287 std::shared_ptr<ContentContext> renderer = GetContentContext();
291 std::optional<Entity> result =
292 contents->GetEntity(*renderer, entity, {});
294 EXPECT_TRUE(result.has_value());
295 if (result.has_value()) {
297 std::optional<Rect> result_coverage = result.value().GetCoverage();
298 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
299 EXPECT_TRUE(result_coverage.has_value());
300 EXPECT_TRUE(contents_coverage.has_value());
301 if (result_coverage.has_value() && contents_coverage.has_value()) {
302 EXPECT_TRUE(
RectNear(contents_coverage.value(),
311 RenderCoverageMatchesGetCoverageRotated) {
312 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(400, 300));
314 CalculateSigmaForBlurRadius(1.0,
Matrix());
315 auto contents = std::make_unique<GaussianBlurFilterContents>(
320 std::shared_ptr<ContentContext> renderer = GetContentContext();
326 std::optional<Entity> result =
327 contents->GetEntity(*renderer, entity, {});
328 EXPECT_TRUE(result.has_value());
329 if (result.has_value()) {
331 std::optional<Rect> result_coverage = result.value().GetCoverage();
332 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
333 EXPECT_TRUE(result_coverage.has_value());
334 EXPECT_TRUE(contents_coverage.has_value());
335 if (result_coverage.has_value() && contents_coverage.has_value()) {
336 EXPECT_TRUE(
RectNear(contents_coverage.value(),
345 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
351 EXPECT_TRUE(uvs_bounds.has_value());
352 if (uvs_bounds.has_value()) {
358 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
359 auto texture_contents = std::make_shared<TextureContents>();
361 texture_contents->SetTexture(
texture);
366 CalculateSigmaForBlurRadius(1.0,
Matrix());
367 auto contents = std::make_unique<GaussianBlurFilterContents>(
372 std::shared_ptr<ContentContext> renderer = GetContentContext();
375 std::optional<Entity> result =
376 contents->GetEntity(*renderer, entity, {});
377 EXPECT_TRUE(result.has_value());
378 if (result.has_value()) {
380 std::optional<Rect> result_coverage = result.value().GetCoverage();
381 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
382 EXPECT_TRUE(result_coverage.has_value());
383 EXPECT_TRUE(contents_coverage.has_value());
384 if (result_coverage.has_value() && contents_coverage.has_value()) {
385 EXPECT_TRUE(
RectNear(result_coverage.value(), contents_coverage.value()));
386 EXPECT_TRUE(
RectNear(result_coverage.value(),
393 TextureContentsWithDestinationRectScaled) {
394 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
395 auto texture_contents = std::make_shared<TextureContents>();
397 texture_contents->SetTexture(
texture);
402 CalculateSigmaForBlurRadius(1.0,
Matrix());
403 auto contents = std::make_unique<GaussianBlurFilterContents>(
408 std::shared_ptr<ContentContext> renderer = GetContentContext();
412 std::optional<Entity> result =
413 contents->GetEntity(*renderer, entity, {});
414 EXPECT_TRUE(result.has_value());
415 if (result.has_value()) {
417 std::optional<Rect> result_coverage = result.value().GetCoverage();
418 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
419 EXPECT_TRUE(result_coverage.has_value());
420 EXPECT_TRUE(contents_coverage.has_value());
421 if (result_coverage.has_value() && contents_coverage.has_value()) {
422 EXPECT_TRUE(
RectNear(result_coverage.value(), contents_coverage.value()));
426 EXPECT_TRUE(
RectNear(contents_coverage.value(),
434 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
435 auto texture_contents = std::make_shared<TextureContents>();
437 texture_contents->SetTexture(
texture);
442 CalculateSigmaForBlurRadius(1.0, effect_transform);
443 ASSERT_TRUE(sigma_radius_1.
ok());
444 auto contents = std::make_unique<GaussianBlurFilterContents>(
449 contents->SetEffectTransform(effect_transform);
450 std::shared_ptr<ContentContext> renderer = GetContentContext();
453 std::optional<Entity> result =
454 contents->GetEntity(*renderer, entity, {});
455 EXPECT_TRUE(result.has_value());
456 if (result.has_value()) {
458 std::optional<Rect> result_coverage = result.value().GetCoverage();
459 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
460 EXPECT_TRUE(result_coverage.has_value());
461 EXPECT_TRUE(contents_coverage.has_value());
462 if (result_coverage.has_value() && contents_coverage.has_value()) {
463 EXPECT_TRUE(
RectNear(result_coverage.value(), contents_coverage.value()));
464 EXPECT_TRUE(
RectNear(contents_coverage.value(),
475 CalculateSigmaForBlurRadius(radius,
Matrix());
476 ASSERT_TRUE(derived_sigma.
ok());
477 EXPECT_NEAR(sigma, derived_sigma.
value(), 0.01f);
493 EXPECT_FLOAT_EQ(tally, 1.0f);
496 for (
int i = 0;
i < 4; ++
i) {
532 GaussianBlurPipeline::FragmentShader::KernelSamples blur_info =
534 EXPECT_EQ(blur_info.sample_count, 3);
542 Point(-1.3333333, 0));
543 EXPECT_FLOAT_EQ(GetCoefficient(blur_info.sample_data[0]), 0.3);
546 EXPECT_FLOAT_EQ(GetCoefficient(blur_info.sample_data[1]), 0.4);
549 EXPECT_FLOAT_EQ(GetCoefficient(blur_info.sample_data[2]), 0.3);
562 Scalar fract = fabsf(modf(point.
x, &int_part));
564 return left * fract + right * (1.0 - fract);
566 return left * (1.0 - fract) + right * fract;
570 lerp(GetUVOffset(blur_info.sample_data[0]),
data[0],
data[1]) *
571 GetCoefficient(blur_info.sample_data[0]) +
572 data[2] * GetCoefficient(blur_info.sample_data[1]) +
573 lerp(GetUVOffset(blur_info.sample_data[2]),
data[3],
data[4]) *
574 GetCoefficient(blur_info.sample_data[2]);
576 EXPECT_NEAR(original_output, fast_output, 0.01);
589 GaussianBlurPipeline::FragmentShader::KernelSamples fast_kernel_samples =
591 EXPECT_EQ(fast_kernel_samples.sample_count, 17);
594 for (
int i = 0;
i < 33;
i++) {
603 Scalar fract = fabsf(modf(point.x, &fint_part));
605 int32_t int_part =
static_cast<int32_t
>(fint_part) + 16;
606 return data[int_part];
608 int32_t left =
static_cast<int32_t
>(floor(point.x)) + 16;
609 int32_t right =
static_cast<int32_t
>(ceil(point.x)) + 16;
611 return fract *
data[left] + (1.0 - fract) *
data[right];
613 return (1.0 - fract) *
data[left] + fract *
data[right];
620 auto sample = kernel_samples.
samples[
i];
621 output += sample.
coefficient * sampler(sample.uv_offset);
625 for (
int i = 0;
i < fast_kernel_samples.sample_count;
i++) {
626 fast_output += GetCoefficient(fast_kernel_samples.sample_data[
i]) *
627 sampler(GetUVOffset(fast_kernel_samples.sample_data[
i]));
630 EXPECT_NEAR(output, fast_output, 0.1);
642 GaussianBlurPipeline::FragmentShader::KernelSamples frag_kernel_samples =
void SetTransform(const Matrix &transform)
Set the global transform matrix for this Entity.
std::shared_ptr< ContentContext > GetContentContext() const
@ kNormal
Blurred inside and outside.
Performs a bidirectional Gaussian blur.
static Scalar CalculateBlurRadius(Scalar sigma)
static Scalar ScaleSigma(Scalar sigma)
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...
static Scalar CalculateScale(Scalar sigma)
static Quad CalculateUVs(const std::shared_ptr< FilterInput > &filter_input, const Entity &entity, const Rect &source_rect, const ISize &texture_size)
std::shared_ptr< Context > GetContext() const
Render passes encode render commands directed as one specific render target into an underlying comman...
std::shared_ptr< Texture > MakeTexture(ISize size)
Create a texture that has been cleared to transparent black.
#define FML_CHECK(condition)
Vector2 blur_radius
Blur radius in source pixels based on scaled_sigma.
Vector2 scaled_sigma
Sigma when considering an entity's scale and the effect transform.
inline ::testing::AssertionResult RectNear(impeller::Rect a, impeller::Rect b)
#define EXPECT_RECT_NEAR(a, b)
#define EXPECT_POINT_NEAR(a, b)
TEST(FrameTimingsRecorderTest, RecordVsync)
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
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
TEST_P(AiksTest, DrawAtlasNoColor)
static constexpr int32_t kGaussianBlurMaxKernelSize
KernelSamples GenerateBlurInfo(BlurParameters parameters)
std::array< Point, 4 > Quad
GaussianBlurPipeline::FragmentShader::KernelSamples LerpHackKernelSamples(KernelSamples parameters)
#define INSTANTIATE_PLAYGROUND_SUITE(playground)
KernelSample samples[kMaxKernelSize]
A 4x4 matrix using column-major storage.
static constexpr Matrix MakeTranslation(const Vector3 &t)
static Matrix MakeRotationZ(Radians r)
static constexpr Matrix MakeScale(const Vector3 &s)
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
static constexpr TRect MakeSize(const TSize< U > &size)
static constexpr std::optional< TRect > MakePointBounds(const U &value)
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)