Skip to content

Commit

Permalink
[Impeller] moved tests to aiks_blur_unittests, added warning (flutter…
Browse files Browse the repository at this point in the history
…#51274)

issue: flutter/flutter#140106

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide] and the [C++,
Objective-C, Java style guides].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I added new tests to check the change I am making or feature I am
adding, or the PR is [test-exempt]. See [testing the engine] for
instructions on writing and running engine tests.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I signed the [CLA].
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#overview
[Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene
[test-exempt]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo
[C++, Objective-C, Java style guides]:
https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
[testing the engine]:
https://github.com/flutter/flutter/wiki/Testing-the-engine
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes
[Discord]: https://github.com/flutter/flutter/wiki/Chat
  • Loading branch information
gaaclarke committed Mar 8, 2024
1 parent bbb1ed0 commit 68f1d69
Show file tree
Hide file tree
Showing 2 changed files with 193 additions and 183 deletions.
183 changes: 183 additions & 0 deletions impeller/aiks/aiks_blur_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "flutter/impeller/aiks/aiks_unittests.h"

#include "impeller/aiks/canvas.h"
#include "impeller/entity/contents/filters/gaussian_blur_filter_contents.h"
#include "impeller/entity/render_target_cache.h"
#include "impeller/geometry/path_builder.h"
#include "impeller/playground/widgets.h"
Expand Down Expand Up @@ -672,5 +673,187 @@ TEST_P(AiksTest, GaussianBlurStyleSolid) {
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}

TEST_P(AiksTest, GuassianBlurUpdatesMipmapContents) {
// This makes sure if mip maps are recycled across invocations of blurs the
// contents get updated each frame correctly. If they aren't updated the color
// inside the blur and outside the blur will be different.
//
// If there is some change to render target caching this could display a false
// positive in the future. Also, if the LOD that is rendered is 1 it could
// present a false positive.
int32_t count = 0;
auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
Canvas canvas;
if (count++ == 0) {
canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
} else {
canvas.DrawCircle({100, 100}, 50, {.color = Color::Chartreuse()});
}
canvas.ClipRRect(Rect::MakeLTRB(75, 50, 375, 275), {20, 20});
canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
ImageFilter::MakeBlur(Sigma(30.0), Sigma(30.0),
FilterContents::BlurStyle::kNormal,
Entity::TileMode::kClamp));
canvas.Restore();
return canvas.EndRecordingAsPicture();
};

ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(AiksTest, GaussianBlurSetsMipCountOnPass) {
Canvas canvas;
canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
canvas.SaveLayer({}, std::nullopt,
ImageFilter::MakeBlur(Sigma(3), Sigma(3),
FilterContents::BlurStyle::kNormal,
Entity::TileMode::kClamp));
canvas.Restore();

Picture picture = canvas.EndRecordingAsPicture();
EXPECT_EQ(4, picture.pass->GetRequiredMipCount());
}

TEST_P(AiksTest, GaussianBlurAllocatesCorrectMipCountRenderTarget) {
size_t blur_required_mip_count =
GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;

Canvas canvas;
canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
canvas.SaveLayer({}, std::nullopt,
ImageFilter::MakeBlur(Sigma(3), Sigma(3),
FilterContents::BlurStyle::kNormal,
Entity::TileMode::kClamp));
canvas.Restore();

Picture picture = canvas.EndRecordingAsPicture();
std::shared_ptr<RenderTargetCache> cache =
std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
AiksContext aiks_context(GetContext(), nullptr, cache);
picture.ToImage(aiks_context, {100, 100});

size_t max_mip_count = 0;
for (auto it = cache->GetRenderTargetDataBegin();
it != cache->GetRenderTargetDataEnd(); ++it) {
max_mip_count = std::max(it->config.mip_count, max_mip_count);
}
EXPECT_EQ(max_mip_count, blur_required_mip_count);
}

TEST_P(AiksTest, GaussianBlurMipMapNestedLayer) {
fml::testing::LogCapture log_capture;
size_t blur_required_mip_count =
GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;

Canvas canvas;
canvas.DrawPaint({.color = Color::Wheat()});
canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
canvas.SaveLayer({}, std::nullopt,
ImageFilter::MakeBlur(Sigma(30), Sigma(30),
FilterContents::BlurStyle::kNormal,
Entity::TileMode::kClamp));
canvas.DrawCircle({200, 200}, 50, {.color = Color::Chartreuse()});

Picture picture = canvas.EndRecordingAsPicture();
std::shared_ptr<RenderTargetCache> cache =
std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
AiksContext aiks_context(GetContext(), nullptr, cache);
picture.ToImage(aiks_context, {100, 100});

size_t max_mip_count = 0;
for (auto it = cache->GetRenderTargetDataBegin();
it != cache->GetRenderTargetDataEnd(); ++it) {
max_mip_count = std::max(it->config.mip_count, max_mip_count);
}
EXPECT_EQ(max_mip_count, blur_required_mip_count);
// The log is FML_DLOG, so only check in debug builds.
#ifndef NDEBUG
if (GetParam() != PlaygroundBackend::kOpenGLES) {
EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
std::string::npos);
} else {
EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
std::string::npos);
}
#endif
}

TEST_P(AiksTest, GaussianBlurMipMapImageFilter) {
size_t blur_required_mip_count =
GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;
fml::testing::LogCapture log_capture;
Canvas canvas;
canvas.SaveLayer(
{.image_filter = ImageFilter::MakeBlur(Sigma(30), Sigma(30),
FilterContents::BlurStyle::kNormal,
Entity::TileMode::kClamp)});
canvas.DrawCircle({200, 200}, 50, {.color = Color::Chartreuse()});

Picture picture = canvas.EndRecordingAsPicture();
std::shared_ptr<RenderTargetCache> cache =
std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
AiksContext aiks_context(GetContext(), nullptr, cache);
picture.ToImage(aiks_context, {1024, 768});

size_t max_mip_count = 0;
for (auto it = cache->GetRenderTargetDataBegin();
it != cache->GetRenderTargetDataEnd(); ++it) {
max_mip_count = std::max(it->config.mip_count, max_mip_count);
}
EXPECT_EQ(max_mip_count, blur_required_mip_count);
// The log is FML_DLOG, so only check in debug builds.
#ifndef NDEBUG
if (GetParam() != PlaygroundBackend::kOpenGLES) {
EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
std::string::npos);
} else {
EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
std::string::npos);
}
#endif
}

TEST_P(AiksTest, GaussianBlurMipMapSolidColor) {
size_t blur_required_mip_count =
GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;
fml::testing::LogCapture log_capture;
Canvas canvas;
canvas.DrawPath(PathBuilder{}
.MoveTo({100, 100})
.LineTo({200, 100})
.LineTo({150, 200})
.LineTo({50, 200})
.Close()
.TakePath(),
{.color = Color::Chartreuse(),
.image_filter = ImageFilter::MakeBlur(
Sigma(30), Sigma(30), FilterContents::BlurStyle::kNormal,
Entity::TileMode::kClamp)});

Picture picture = canvas.EndRecordingAsPicture();
std::shared_ptr<RenderTargetCache> cache =
std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
AiksContext aiks_context(GetContext(), nullptr, cache);
picture.ToImage(aiks_context, {1024, 768});

size_t max_mip_count = 0;
for (auto it = cache->GetRenderTargetDataBegin();
it != cache->GetRenderTargetDataEnd(); ++it) {
max_mip_count = std::max(it->config.mip_count, max_mip_count);
}
EXPECT_EQ(max_mip_count, blur_required_mip_count);
// The log is FML_DLOG, so only check in debug builds.
#ifndef NDEBUG
if (GetParam() != PlaygroundBackend::kOpenGLES) {
EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
std::string::npos);
} else {
EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
std::string::npos);
}
#endif
}

} // namespace testing
} // namespace impeller
Loading

0 comments on commit 68f1d69

Please sign in to comment.