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();
127 std::optional<Rect> coverage =
129 ASSERT_FALSE(coverage.has_value());
139 std::optional<Rect> coverage =
147 CalculateSigmaForBlurRadius(1.0,
Matrix());
148 ASSERT_TRUE(sigma_radius_1.
ok());
150 sigma_radius_1.
value(),
156 std::optional<Rect> coverage =
159 EXPECT_TRUE(coverage.has_value());
160 if (coverage.has_value()) {
167 CalculateSigmaForBlurRadius(1.0,
Matrix());
168 ASSERT_TRUE(sigma_radius_1.
ok());
170 sigma_radius_1.
value(),
173 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
177 std::optional<Rect> coverage =
180 EXPECT_TRUE(coverage.has_value());
181 if (coverage.has_value()) {
189 CalculateSigmaForBlurRadius(1.0, effect_transform);
190 ASSERT_TRUE(sigma_radius_1.ok());
192 sigma_radius_1.value(),
195 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
199 std::optional<Rect> coverage =
201 EXPECT_TRUE(coverage.has_value());
202 if (coverage.has_value()) {
210 CalculateSigmaForBlurRadius(1.0,
Matrix());
211 ASSERT_TRUE(sigma_radius_1.
ok());
212 auto contents = std::make_unique<GaussianBlurFilterContents>(
215 std::optional<Rect> coverage = contents->GetFilterSourceCoverage(
218 EXPECT_TRUE(coverage.has_value());
219 if (coverage.has_value()) {
239 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
241 CalculateSigmaForBlurRadius(1.0,
Matrix());
242 ASSERT_TRUE(sigma_radius_1.
ok());
243 auto contents = std::make_unique<GaussianBlurFilterContents>(
247 std::shared_ptr<ContentContext> renderer = GetContentContext();
250 std::optional<Entity> result =
251 contents->GetEntity(*renderer, entity, {});
252 EXPECT_TRUE(result.has_value());
253 if (result.has_value()) {
255 std::optional<Rect> result_coverage = result.value().GetCoverage();
256 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
257 EXPECT_TRUE(result_coverage.has_value());
258 EXPECT_TRUE(contents_coverage.has_value());
259 if (result_coverage.has_value() && contents_coverage.has_value()) {
260 EXPECT_TRUE(
RectNear(contents_coverage.value(),
269 RenderCoverageMatchesGetCoverageTranslate) {
270 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
272 CalculateSigmaForBlurRadius(1.0,
Matrix());
273 ASSERT_TRUE(sigma_radius_1.
ok());
274 auto contents = std::make_unique<GaussianBlurFilterContents>(
278 std::shared_ptr<ContentContext> renderer = GetContentContext();
282 std::optional<Entity> result =
283 contents->GetEntity(*renderer, entity, {});
285 EXPECT_TRUE(result.has_value());
286 if (result.has_value()) {
288 std::optional<Rect> result_coverage = result.value().GetCoverage();
289 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
290 EXPECT_TRUE(result_coverage.has_value());
291 EXPECT_TRUE(contents_coverage.has_value());
292 if (result_coverage.has_value() && contents_coverage.has_value()) {
293 EXPECT_TRUE(
RectNear(contents_coverage.value(),
302 RenderCoverageMatchesGetCoverageRotated) {
303 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(400, 300));
305 CalculateSigmaForBlurRadius(1.0,
Matrix());
306 auto contents = std::make_unique<GaussianBlurFilterContents>(
310 std::shared_ptr<ContentContext> renderer = GetContentContext();
316 std::optional<Entity> result =
317 contents->GetEntity(*renderer, entity, {});
318 EXPECT_TRUE(result.has_value());
319 if (result.has_value()) {
321 std::optional<Rect> result_coverage = result.value().GetCoverage();
322 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
323 EXPECT_TRUE(result_coverage.has_value());
324 EXPECT_TRUE(contents_coverage.has_value());
325 if (result_coverage.has_value() && contents_coverage.has_value()) {
326 EXPECT_TRUE(
RectNear(contents_coverage.value(),
335 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
341 EXPECT_TRUE(uvs_bounds.has_value());
342 if (uvs_bounds.has_value()) {
348 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
349 auto texture_contents = std::make_shared<TextureContents>();
351 texture_contents->SetTexture(
texture);
356 CalculateSigmaForBlurRadius(1.0,
Matrix());
357 auto contents = std::make_unique<GaussianBlurFilterContents>(
361 std::shared_ptr<ContentContext> renderer = GetContentContext();
364 std::optional<Entity> result =
365 contents->GetEntity(*renderer, entity, {});
366 EXPECT_TRUE(result.has_value());
367 if (result.has_value()) {
369 std::optional<Rect> result_coverage = result.value().GetCoverage();
370 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
371 EXPECT_TRUE(result_coverage.has_value());
372 EXPECT_TRUE(contents_coverage.has_value());
373 if (result_coverage.has_value() && contents_coverage.has_value()) {
374 EXPECT_TRUE(
RectNear(result_coverage.value(), contents_coverage.value()));
375 EXPECT_TRUE(
RectNear(result_coverage.value(),
382 TextureContentsWithDestinationRectScaled) {
383 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
384 auto texture_contents = std::make_shared<TextureContents>();
386 texture_contents->SetTexture(
texture);
391 CalculateSigmaForBlurRadius(1.0,
Matrix());
392 auto contents = std::make_unique<GaussianBlurFilterContents>(
397 std::shared_ptr<ContentContext> renderer = GetContentContext();
401 std::optional<Entity> result =
402 contents->GetEntity(*renderer, entity, {});
403 EXPECT_TRUE(result.has_value());
404 if (result.has_value()) {
406 std::optional<Rect> result_coverage = result.value().GetCoverage();
407 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
408 EXPECT_TRUE(result_coverage.has_value());
409 EXPECT_TRUE(contents_coverage.has_value());
410 if (result_coverage.has_value() && contents_coverage.has_value()) {
411 EXPECT_TRUE(
RectNear(result_coverage.value(), contents_coverage.value()));
415 EXPECT_TRUE(
RectNear(contents_coverage.value(),
423 std::shared_ptr<Texture>
texture = MakeTexture(
ISize(100, 100));
424 auto texture_contents = std::make_shared<TextureContents>();
426 texture_contents->SetTexture(
texture);
431 CalculateSigmaForBlurRadius(1.0, effect_transform);
432 ASSERT_TRUE(sigma_radius_1.
ok());
433 auto contents = std::make_unique<GaussianBlurFilterContents>(
437 contents->SetEffectTransform(effect_transform);
438 std::shared_ptr<ContentContext> renderer = GetContentContext();
441 std::optional<Entity> result =
442 contents->GetEntity(*renderer, entity, {});
443 EXPECT_TRUE(result.has_value());
444 if (result.has_value()) {
446 std::optional<Rect> result_coverage = result.value().GetCoverage();
447 std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
448 EXPECT_TRUE(result_coverage.has_value());
449 EXPECT_TRUE(contents_coverage.has_value());
450 if (result_coverage.has_value() && contents_coverage.has_value()) {
451 EXPECT_TRUE(
RectNear(result_coverage.value(), contents_coverage.value()));
452 EXPECT_TRUE(
RectNear(contents_coverage.value(),
463 CalculateSigmaForBlurRadius(radius,
Matrix());
464 ASSERT_TRUE(derived_sigma.
ok());
465 EXPECT_NEAR(sigma, derived_sigma.
value(), 0.01f);
481 EXPECT_FLOAT_EQ(tally, 1.0f);
484 for (
int i = 0;
i < 4; ++
i) {
520 GaussianBlurPipeline::FragmentShader::KernelSamples blur_info =
522 EXPECT_EQ(blur_info.sample_count, 3);
530 Point(-1.3333333, 0));
531 EXPECT_FLOAT_EQ(GetCoefficient(blur_info.sample_data[0]), 0.3);
534 EXPECT_FLOAT_EQ(GetCoefficient(blur_info.sample_data[1]), 0.4);
537 EXPECT_FLOAT_EQ(GetCoefficient(blur_info.sample_data[2]), 0.3);
550 Scalar fract = fabsf(modf(point.
x, &int_part));
552 return left * fract + right * (1.0 - fract);
554 return left * (1.0 - fract) + right * fract;
558 lerp(GetUVOffset(blur_info.sample_data[0]),
data[0],
data[1]) *
559 GetCoefficient(blur_info.sample_data[0]) +
560 data[2] * GetCoefficient(blur_info.sample_data[1]) +
561 lerp(GetUVOffset(blur_info.sample_data[2]),
data[3],
data[4]) *
562 GetCoefficient(blur_info.sample_data[2]);
564 EXPECT_NEAR(original_output, fast_output, 0.01);
577 GaussianBlurPipeline::FragmentShader::KernelSamples fast_kernel_samples =
579 EXPECT_EQ(fast_kernel_samples.sample_count, 17);
582 for (
int i = 0;
i < 33;
i++) {
591 Scalar fract = fabsf(modf(point.x, &fint_part));
593 int32_t int_part =
static_cast<int32_t
>(fint_part) + 16;
594 return data[int_part];
596 int32_t left =
static_cast<int32_t
>(floor(point.x)) + 16;
597 int32_t right =
static_cast<int32_t
>(ceil(point.x)) + 16;
599 return fract *
data[left] + (1.0 - fract) *
data[right];
601 return (1.0 - fract) *
data[left] + fract *
data[right];
608 auto sample = kernel_samples.
samples[
i];
609 output += sample.
coefficient * sampler(sample.uv_offset);
613 for (
int i = 0;
i < fast_kernel_samples.sample_count;
i++) {
614 fast_output += GetCoefficient(fast_kernel_samples.sample_data[
i]) *
615 sampler(GetUVOffset(fast_kernel_samples.sample_data[
i]));
618 EXPECT_NEAR(output, fast_output, 0.1);
630 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.
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)