16#include "gtest/gtest.h"
18#include "include/core/SkMatrix.h"
19#include "third_party/skia/include/core/SkBlendMode.h"
20#include "third_party/skia/include/core/SkColorFilter.h"
21#include "third_party/skia/include/core/SkSamplingOptions.h"
22#include "third_party/skia/include/effects/SkImageFilters.h"
40 return (p.
x >= rect.
GetLeft() - 1E-9 &&
70 const DlRect& sourceBounds,
71 const DlQuad& expectedLocalOutputQuad) {
73 DlQuad expected_output_quad = matrix.
Transform(expectedLocalOutputQuad);
77 matrix, device_filter_ibounds),
78 &device_filter_ibounds);
80 << filter << std::endl
81 << sourceBounds <<
", {" << std::endl
82 <<
" " << expectedLocalOutputQuad[0] <<
", " << std::endl
83 <<
" " << expectedLocalOutputQuad[1] <<
", " << std::endl
84 <<
" " << expectedLocalOutputQuad[2] <<
", " << std::endl
85 <<
" " << expectedLocalOutputQuad[3] << std::endl
86 <<
"}, " << matrix <<
", " << std::endl
87 << device_filter_ibounds << std::endl
88 << device_input_bounds <<
", {" << std::endl
89 <<
" " << expected_output_quad[0] <<
", " << std::endl
90 <<
" " << expected_output_quad[1] <<
", " << std::endl
91 <<
" " << expected_output_quad[2] <<
", " << std::endl
92 <<
" " << expected_output_quad[3] << std::endl
97 reverse_input_ibounds),
98 &reverse_input_ibounds);
100 << filter << std::endl
101 << matrix <<
", " << std::endl
102 << reverse_input_ibounds <<
", " << std::endl
103 << device_input_bounds;
108 const DlRect& localInputBounds) {
112 DlRect local_filter_bounds;
115 ASSERT_EQ(local_filter_bounds, localInputBounds);
119 device_filter_ibounds),
121 ASSERT_EQ(device_filter_ibounds, device_input_bounds);
125 reverse_input_ibounds),
127 ASSERT_EQ(reverse_input_ibounds, device_input_bounds);
139 const DlRect& sourceBounds,
140 const DlQuad& expectedLocalOutputQuad) {
141 DlRect local_filter_bounds;
143 &local_filter_bounds);
146 for (
int i_scale = 1; i_scale <= 4; i_scale++) {
148 for (
int skew_eighths = 0; skew_eighths < 7; skew_eighths++) {
149 DlScalar skew = skew_eighths / 8.0f;
150 for (
int degrees = 0; degrees <= 360; degrees += 15) {
152 matrix = matrix.
Scale({scale, scale, 1});
158 expectedLocalOutputQuad);
159 matrix.
m[3] = 0.001f;
160 matrix.
m[7] = 0.001f;
164 expectedLocalOutputQuad);
171 const DlRect& sourceBounds,
172 const DlRect& expectedLocalOutputBounds) {
173 DlQuad expected_local_output_quad = expectedLocalOutputBounds.
GetPoints();
174 ASSERT_EQ(expected_local_output_quad.size(), 4u);
175 TestBounds(filter, sourceBounds, expected_local_output_quad);
178TEST(DisplayListImageFilter, BlurConstructor) {
182TEST(DisplayListImageFilter, BlurShared) {
185 ASSERT_NE(filter.
shared().get(), &filter);
186 ASSERT_EQ(*filter.
shared(), filter);
189TEST(DisplayListImageFilter, BlurAsBlur) {
192 ASSERT_NE(filter.
asBlur(),
nullptr);
193 ASSERT_EQ(filter.
asBlur(), &filter);
196TEST(DisplayListImageFilter, BlurContents) {
199 ASSERT_EQ(filter.
sigma_x(), 5.0);
200 ASSERT_EQ(filter.
sigma_y(), 6.0);
204TEST(DisplayListImageFilter, BlurEquals) {
218TEST(DisplayListImageFilter, BlurWithLocalMatrixEquals) {
227TEST(DisplayListImageFilter, BlurNotEquals) {
244TEST(DisplayListImageFilter, BlurBounds) {
247 DlRect expected_output_bounds = input_bounds.
Expand(15, 30);
248 TestBounds(filter, input_bounds, expected_output_bounds);
251TEST(DisplayListImageFilter, BlurZeroSigma) {
252 std::shared_ptr<DlImageFilter> filter =
254 ASSERT_EQ(filter,
nullptr);
256 ASSERT_EQ(filter,
nullptr);
258 ASSERT_EQ(filter,
nullptr);
261 ASSERT_EQ(filter,
nullptr);
263 ASSERT_NE(filter,
nullptr);
265 ASSERT_NE(filter,
nullptr);
268TEST(DisplayListImageFilter, DilateConstructor) {
272TEST(DisplayListImageFilter, DilateShared) {
275 ASSERT_NE(filter.
shared().get(), &filter);
276 ASSERT_EQ(*filter.
shared(), filter);
279TEST(DisplayListImageFilter, DilateAsDilate) {
282 ASSERT_NE(filter.
asDilate(),
nullptr);
283 ASSERT_EQ(filter.
asDilate(), &filter);
286TEST(DisplayListImageFilter, DilateContents) {
293TEST(DisplayListImageFilter, DilateEquals) {
300TEST(DisplayListImageFilter, DilateWithLocalMatrixEquals) {
309TEST(DisplayListImageFilter, DilateNotEquals) {
318TEST(DisplayListImageFilter, DilateBounds) {
321 DlRect expected_output_bounds = input_bounds.
Expand(5, 10);
322 TestBounds(filter, input_bounds, expected_output_bounds);
325TEST(DisplayListImageFilter, ErodeConstructor) {
329TEST(DisplayListImageFilter, ErodeShared) {
332 ASSERT_NE(filter.
shared().get(), &filter);
333 ASSERT_EQ(*filter.
shared(), filter);
336TEST(DisplayListImageFilter, ErodeAsErode) {
339 ASSERT_NE(filter.
asErode(),
nullptr);
340 ASSERT_EQ(filter.
asErode(), &filter);
343TEST(DisplayListImageFilter, ErodeContents) {
350TEST(DisplayListImageFilter, ErodeEquals) {
357TEST(DisplayListImageFilter, ErodeWithLocalMatrixEquals) {
366TEST(DisplayListImageFilter, ErodeNotEquals) {
375TEST(DisplayListImageFilter, ErodeBounds) {
378 DlRect expected_output_bounds = input_bounds.
Expand(-5, -10);
379 TestBounds(filter, input_bounds, expected_output_bounds);
382TEST(DisplayListImageFilter, MatrixConstructor) {
390TEST(DisplayListImageFilter, MatrixShared) {
397 ASSERT_NE(filter.
shared().get(), &filter);
398 ASSERT_EQ(*filter.
shared(), filter);
401TEST(DisplayListImageFilter, MatrixAsMatrix) {
408 ASSERT_NE(filter.
asMatrix(),
nullptr);
409 ASSERT_EQ(filter.
asMatrix(), &filter);
412TEST(DisplayListImageFilter, MatrixContents) {
419 ASSERT_EQ(filter.
matrix(), matrix);
423TEST(DisplayListImageFilter, MatrixEquals) {
434TEST(DisplayListImageFilter, MatrixWithLocalMatrixEquals) {
447TEST(DisplayListImageFilter, MatrixNotEquals) {
464TEST(DisplayListImageFilter, MatrixBounds) {
472 DlQuad expectedOutputQuad = {
478 TestBounds(filter, input_bounds, expectedOutputQuad);
481TEST(DisplayListImageFilter, ComposeConstructor) {
491TEST(DisplayListImageFilter, ComposeShared) {
500 ASSERT_NE(filter.
shared().get(), &filter);
501 ASSERT_EQ(*filter.
shared(), filter);
504TEST(DisplayListImageFilter, ComposeAsCompose) {
517TEST(DisplayListImageFilter, ComposeContents) {
526 ASSERT_EQ(*filter.
outer().get(), outer);
527 ASSERT_EQ(*filter.
inner().get(), inner);
530TEST(DisplayListImageFilter, ComposeEquals) {
550TEST(DisplayListImageFilter, ComposeWithLocalMatrixEquals) {
572TEST(DisplayListImageFilter, ComposeNotEquals) {
595TEST(DisplayListImageFilter, ComposeBounds) {
601 TestBounds(filter, input_bounds, expected_output_bounds);
605 const DlRect& sourceBounds,
606 const DlRect& expectedOutputBounds,
607 const DlRect& expectedInputBounds) {
610 EXPECT_EQ(bounds, expectedOutputBounds);
624TEST(DisplayListImageFilter, ComposeBoundsWithUnboundedInner) {
636TEST(DisplayListImageFilter, ComposeBoundsWithUnboundedOuter) {
648TEST(DisplayListImageFilter, ComposeBoundsWithUnboundedInnerAndOuter) {
650 auto expected_bounds = input_bounds;
662TEST(DisplayListImageFilter, Issue108433) {
672 ASSERT_EQ(dl_compose.map_device_bounds(input_bounds,
DlMatrix(), dl_bounds),
674 ASSERT_EQ(dl_bounds, expected_bounds);
677TEST(DisplayListImageFilter, ColorFilterConstructor) {
682TEST(DisplayListImageFilter, ColorFilterShared) {
686 ASSERT_EQ(*filter.
shared(), filter);
689TEST(DisplayListImageFilter, ColorFilterAsColorFilter) {
701 ASSERT_EQ(*filter.
color_filter().get(), dl_color_filter);
704TEST(DisplayListImageFilter, ColorFilterEquals) {
714TEST(DisplayListImageFilter, ColorFilterWithLocalMatrixEquals) {
726TEST(DisplayListImageFilter, ColorFilterNotEquals) {
740TEST(DisplayListImageFilter, ColorFilterBounds) {
744 TestBounds(filter, input_bounds, input_bounds);
747TEST(DisplayListImageFilter, ColorFilterModifiesTransparencyBounds) {
754TEST(DisplayListImageFilter, LocalImageFilterBounds) {
759 std::vector<sk_sp<SkImageFilter>> sk_filters{
760 SkImageFilters::Blur(5.0, 6.0, SkTileMode::kRepeat,
nullptr),
761 SkImageFilters::ColorFilter(
762 SkColorFilters::Blend(SK_ColorRED, SkBlendMode::kSrcOver),
nullptr),
763 SkImageFilters::Dilate(5.0, 10.0,
nullptr),
764 SkImageFilters::MatrixTransform(
ToSkMatrix(filter_matrix),
765 SkSamplingOptions(SkFilterMode::kLinear),
767 SkImageFilters::Compose(
768 SkImageFilters::Blur(5.0, 6.0, SkTileMode::kRepeat,
nullptr),
769 SkImageFilters::ColorFilter(
770 SkColorFilters::Blend(SK_ColorRED, SkBlendMode::kSrcOver),
774 std::vector<std::shared_ptr<DlImageFilter>> dl_filters{
784 auto persp = SkMatrix::I();
785 persp.setPerspY(0.001);
786 std::vector<SkMatrix> sk_matrices = {
787 SkMatrix::Translate(10.0, 10.0),
788 SkMatrix::Scale(2.0, 2.0).preTranslate(10.0, 10.0),
789 SkMatrix::RotateDeg(45).preTranslate(5.0, 5.0),
791 std::vector<DlMatrix> dl_matrices = {
796 std::vector<SkMatrix> sk_bounds_matrices{
797 SkMatrix::Translate(5.0, 10.0),
798 SkMatrix::Scale(2.0, 2.0),
800 std::vector<DlMatrix> dl_bounds_matrices{
805 for (
unsigned j = 0; j < dl_matrices.size(); j++) {
812 EXPECT_EQ(input_bounds, output_bounds);
814 for (
unsigned k = 0; k < dl_bounds_matrices.size(); k++) {
815 auto& bounds_matrix = dl_bounds_matrices[k];
822 EXPECT_EQ(input_bounds, output_bounds);
830 EXPECT_EQ(input_bounds, output_bounds);
835 for (
unsigned i = 0;
i < sk_filters.size();
i++) {
836 for (
unsigned j = 0; j < dl_matrices.size(); j++) {
837 for (
unsigned k = 0; k < dl_bounds_matrices.size(); k++) {
838 auto desc =
"filter " + std::to_string(
i + 1)
839 +
", filter matrix " + std::to_string(j + 1)
840 +
", bounds matrix " + std::to_string(k + 1);
841 auto sk_local_filter =
842 sk_filters[
i]->makeWithLocalMatrix(sk_matrices[j]);
843 auto dl_local_filter =
844 dl_filters[
i]->makeWithLocalMatrix(dl_matrices[j]);
845 if (!sk_local_filter || !dl_local_filter) {
850 ASSERT_TRUE(sk_local_filter || !dl_local_filter) << desc;
854 auto input_bounds = SkIRect::MakeLTRB(20, 20, 80, 80);
857 sk_rect = sk_local_filter->filterBounds(
858 input_bounds, sk_bounds_matrices[k],
859 SkImageFilter::MapDirection::kForward_MapDirection);
860 if (dl_local_filter->map_device_bounds(
861 ToDlIRect(input_bounds), dl_bounds_matrices[k], dl_rect)) {
864 ASSERT_TRUE(dl_local_filter->modifies_transparent_black()) << desc;
865 ASSERT_FALSE(sk_local_filter->canComputeFastBounds()) << desc;
874 if (
i == 2 ||
i == 3) {
877 auto outset_bounds = SkIRect::MakeLTRB(20, 20, 80, 80);
880 sk_rect = sk_local_filter->filterBounds(
881 outset_bounds, sk_bounds_matrices[k],
882 SkImageFilter::MapDirection::kReverse_MapDirection);
883 if (dl_local_filter->get_input_device_bounds(
884 ToDlIRect(outset_bounds), dl_bounds_matrices[k], dl_rect)) {
887 ASSERT_TRUE(dl_local_filter->modifies_transparent_black());
888 ASSERT_FALSE(sk_local_filter->canComputeFastBounds());
896TEST(DisplayListImageFilter, RuntimeEffectEquality) {
898 std::make_shared<std::vector<uint8_t>>());
900 std::make_shared<std::vector<uint8_t>>());
902 EXPECT_EQ(filter_a, filter_b);
905 nullptr, {
nullptr}, std::make_shared<std::vector<uint8_t>>(1));
907 EXPECT_NE(filter_a, filter_c);
910TEST(DisplayListImageFilter, RuntimeEffectEqualityWithSamplers) {
917 std::make_shared<std::vector<uint8_t>>());
919 std::make_shared<std::vector<uint8_t>>());
921 EXPECT_EQ(filter_a, filter_b);
924 std::make_shared<std::vector<uint8_t>>());
926 EXPECT_NE(filter_a, filter_c);
929TEST(DisplayListImageFilter, RuntimeEffectMapDeviceBounds) {
931 std::make_shared<std::vector<uint8_t>>());
939 EXPECT_NE(result,
nullptr);
940 EXPECT_EQ(result, &output_bounds);
941 EXPECT_EQ(output_bounds, input_bounds);
944TEST(DisplayListImageFilter, RuntimeEffectMapInputBounds) {
946 std::make_shared<std::vector<uint8_t>>());
953 EXPECT_NE(result,
nullptr);
954 EXPECT_EQ(result, &output_bounds);
955 EXPECT_EQ(output_bounds, input_bounds);
958TEST(DisplayListImageFilter, RuntimeEffectGetInputDeviceBounds) {
960 std::make_shared<std::vector<uint8_t>>());
969 EXPECT_NE(result,
nullptr);
970 EXPECT_EQ(result, &input_bounds);
971 EXPECT_EQ(output_bounds, input_bounds);
974TEST(DisplayListImageFilter, RuntimeEffectModifiesTransparentBlack) {
976 std::make_shared<std::vector<uint8_t>>());
std::shared_ptr< DlColorFilter > shared() const override
std::shared_ptr< DlImageFilter > shared() const override
const DlBlurImageFilter * asBlur() const override
DlTileMode tile_mode() const
const std::shared_ptr< const DlColorFilter > color_filter() const
const DlColorFilterImageFilter * asColorFilter() const override
std::shared_ptr< DlImageFilter > shared() const override
static std::shared_ptr< DlColorSource > MakeImage(const sk_sp< const DlImage > &image, DlTileMode horizontal_tile_mode, DlTileMode vertical_tile_mode, DlImageSampling sampling=DlImageSampling::kLinear, const DlMatrix *matrix=nullptr)
std::shared_ptr< DlImageFilter > shared() const override
std::shared_ptr< DlImageFilter > inner() const
std::shared_ptr< DlImageFilter > outer() const
const DlComposeImageFilter * asCompose() const override
DlScalar radius_x() const
const DlDilateImageFilter * asDilate() const override
std::shared_ptr< DlImageFilter > shared() const override
DlScalar radius_y() const
const DlErodeImageFilter * asErode() const override
std::shared_ptr< DlImageFilter > shared() const override
DlScalar radius_y() const
DlScalar radius_x() const
static std::shared_ptr< DlImageFilter > MakeDilate(DlScalar radius_x, DlScalar radius_y)
virtual std::shared_ptr< DlImageFilter > makeWithLocalMatrix(const DlMatrix &matrix) const
virtual DlIRect * map_device_bounds(const DlIRect &input_bounds, const DlMatrix &ctm, DlIRect &output_bounds) const =0
static std::shared_ptr< DlImageFilter > MakeBlur(DlScalar sigma_x, DlScalar sigma_y, DlTileMode tile_mode)
static std::shared_ptr< DlImageFilter > MakeColorFilter(const std::shared_ptr< const DlColorFilter > &filter)
virtual DlRect * map_local_bounds(const DlRect &input_bounds, DlRect &output_bounds) const =0
static std::shared_ptr< DlImageFilter > MakeMatrix(const DlMatrix &matrix, DlImageSampling sampling)
static std::shared_ptr< DlImageFilter > MakeCompose(const std::shared_ptr< DlImageFilter > &outer, const std::shared_ptr< DlImageFilter > &inner)
virtual DlIRect * get_input_device_bounds(const DlIRect &output_bounds, const DlMatrix &ctm, DlIRect &input_bounds) const =0
DlIRect * map_device_bounds(const DlIRect &input_bounds, const DlMatrix &ctm, DlIRect &output_bounds) const override
DlIRect * get_input_device_bounds(const DlIRect &output_bounds, const DlMatrix &ctm, DlIRect &input_bounds) const override
DlRect * map_local_bounds(const DlRect &input_bounds, DlRect &output_bounds) const override
const DlMatrixImageFilter * asMatrix() const override
std::shared_ptr< DlImageFilter > shared() const override
DlImageSampling sampling() const
const DlMatrix & matrix() const
DlIRect * map_device_bounds(const DlIRect &input_bounds, const DlMatrix &ctm, DlIRect &output_bounds) const override
bool modifies_transparent_black() const override
DlRect * map_local_bounds(const DlRect &input_bounds, DlRect &output_bounds) const override
DlIRect * get_input_device_bounds(const DlIRect &output_bounds, const DlMatrix &ctm, DlIRect &input_bounds) const override
static void TestBoundsWithMatrix(const DlImageFilter &filter, const DlMatrix &matrix, const DlRect &sourceBounds, const DlQuad &expectedLocalOutputQuad)
static void TestBounds(const DlImageFilter &filter, const DlRect &sourceBounds, const DlQuad &expectedLocalOutputQuad)
static void TestEquals(const T &source1, const U &source2)
static void TestInvalidBounds(const DlImageFilter &filter, const DlMatrix &matrix, const DlRect &localInputBounds)
static void TestNotEquals(T &source1, U &source2, const std::string &label)
TEST(NativeAssetsManagerTest, NoAvailableAssets)
static void TestUnboundedBounds(DlImageFilter &filter, const DlRect &sourceBounds, const DlRect &expectedOutputBounds, const DlRect &expectedInputBounds)
static bool containsInclusive(const DlRect rect, const DlPoint p)
impeller::Scalar DlScalar
impeller::Matrix DlMatrix
impeller::Degrees DlDegrees
const SkIRect & ToSkIRect(const DlIRect &rect)
SkMatrix ToSkMatrix(const DlMatrix &matrix)
const DlIRect & ToDlIRect(const SkIRect &rect)
DlMatrix ToDlMatrix(const SkMatrix &matrix)
static constexpr DlColor kBlue()
static constexpr DlColor kRed()
A 4x4 matrix using column-major storage.
static constexpr Matrix MakeTranslation(const Vector3 &t)
constexpr Matrix Translate(const Vector3 &t) const
bool IsInvertible() const
constexpr bool HasPerspective2D() const
static constexpr Matrix MakeRow(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
static constexpr Matrix MakeSkew(Scalar sx, Scalar sy)
constexpr Quad Transform(const Quad &quad) const
constexpr Matrix Scale(const Vector3 &s) const
static Matrix MakeRotationZ(Radians r)
static constexpr Matrix MakeScale(const Vector3 &s)
constexpr auto GetBottom() const
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
constexpr auto GetTop() const
constexpr std::array< TPoint< T >, 4 > GetPoints() const
Get the points that represent the 4 corners of this rectangle in a Z order that is compatible with tr...
static constexpr std::enable_if_t< std::is_floating_point_v< FT >, TRect > Make(const TRect< U > &rect)
constexpr auto GetLeft() const
RoundOut(const TRect< U > &r)
constexpr auto GetRight() const
constexpr TRect TransformAndClipBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle, clipped against the near clippin...
constexpr TRect< T > Expand(T left, T top, T right, T bottom) const
Returns a rectangle with expanded edges. Negative expansion results in shrinking.
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)