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) {
211TEST(DisplayListImageFilter, BlurWithLocalMatrixEquals) {
220TEST(DisplayListImageFilter, BlurNotEquals) {
231TEST(DisplayListImageFilter, BlurBounds) {
234 DlRect expected_output_bounds = input_bounds.
Expand(15, 30);
235 TestBounds(filter, input_bounds, expected_output_bounds);
238TEST(DisplayListImageFilter, BlurZeroSigma) {
239 std::shared_ptr<DlImageFilter> filter =
241 ASSERT_EQ(filter,
nullptr);
243 ASSERT_EQ(filter,
nullptr);
245 ASSERT_EQ(filter,
nullptr);
248 ASSERT_EQ(filter,
nullptr);
250 ASSERT_NE(filter,
nullptr);
252 ASSERT_NE(filter,
nullptr);
255TEST(DisplayListImageFilter, DilateConstructor) {
259TEST(DisplayListImageFilter, DilateShared) {
262 ASSERT_NE(filter.
shared().get(), &filter);
263 ASSERT_EQ(*filter.
shared(), filter);
266TEST(DisplayListImageFilter, DilateAsDilate) {
269 ASSERT_NE(filter.
asDilate(),
nullptr);
270 ASSERT_EQ(filter.
asDilate(), &filter);
273TEST(DisplayListImageFilter, DilateContents) {
280TEST(DisplayListImageFilter, DilateEquals) {
287TEST(DisplayListImageFilter, DilateWithLocalMatrixEquals) {
296TEST(DisplayListImageFilter, DilateNotEquals) {
305TEST(DisplayListImageFilter, DilateBounds) {
308 DlRect expected_output_bounds = input_bounds.
Expand(5, 10);
309 TestBounds(filter, input_bounds, expected_output_bounds);
312TEST(DisplayListImageFilter, ErodeConstructor) {
316TEST(DisplayListImageFilter, ErodeShared) {
319 ASSERT_NE(filter.
shared().get(), &filter);
320 ASSERT_EQ(*filter.
shared(), filter);
323TEST(DisplayListImageFilter, ErodeAsErode) {
326 ASSERT_NE(filter.
asErode(),
nullptr);
327 ASSERT_EQ(filter.
asErode(), &filter);
330TEST(DisplayListImageFilter, ErodeContents) {
337TEST(DisplayListImageFilter, ErodeEquals) {
344TEST(DisplayListImageFilter, ErodeWithLocalMatrixEquals) {
353TEST(DisplayListImageFilter, ErodeNotEquals) {
362TEST(DisplayListImageFilter, ErodeBounds) {
365 DlRect expected_output_bounds = input_bounds.
Expand(-5, -10);
366 TestBounds(filter, input_bounds, expected_output_bounds);
369TEST(DisplayListImageFilter, MatrixConstructor) {
377TEST(DisplayListImageFilter, MatrixShared) {
384 ASSERT_NE(filter.
shared().get(), &filter);
385 ASSERT_EQ(*filter.
shared(), filter);
388TEST(DisplayListImageFilter, MatrixAsMatrix) {
395 ASSERT_NE(filter.
asMatrix(),
nullptr);
396 ASSERT_EQ(filter.
asMatrix(), &filter);
399TEST(DisplayListImageFilter, MatrixContents) {
406 ASSERT_EQ(filter.
matrix(), matrix);
410TEST(DisplayListImageFilter, MatrixEquals) {
421TEST(DisplayListImageFilter, MatrixWithLocalMatrixEquals) {
434TEST(DisplayListImageFilter, MatrixNotEquals) {
451TEST(DisplayListImageFilter, MatrixBounds) {
459 DlQuad expectedOutputQuad = {
465 TestBounds(filter, input_bounds, expectedOutputQuad);
468TEST(DisplayListImageFilter, ComposeConstructor) {
478TEST(DisplayListImageFilter, ComposeShared) {
487 ASSERT_NE(filter.
shared().get(), &filter);
488 ASSERT_EQ(*filter.
shared(), filter);
491TEST(DisplayListImageFilter, ComposeAsCompose) {
504TEST(DisplayListImageFilter, ComposeContents) {
513 ASSERT_EQ(*filter.
outer().get(), outer);
514 ASSERT_EQ(*filter.
inner().get(), inner);
517TEST(DisplayListImageFilter, ComposeEquals) {
537TEST(DisplayListImageFilter, ComposeWithLocalMatrixEquals) {
559TEST(DisplayListImageFilter, ComposeNotEquals) {
582TEST(DisplayListImageFilter, ComposeBounds) {
588 TestBounds(filter, input_bounds, expected_output_bounds);
592 const DlRect& sourceBounds,
593 const DlRect& expectedOutputBounds,
594 const DlRect& expectedInputBounds) {
597 EXPECT_EQ(bounds, expectedOutputBounds);
611TEST(DisplayListImageFilter, ComposeBoundsWithUnboundedInner) {
623TEST(DisplayListImageFilter, ComposeBoundsWithUnboundedOuter) {
635TEST(DisplayListImageFilter, ComposeBoundsWithUnboundedInnerAndOuter) {
637 auto expected_bounds = input_bounds;
649TEST(DisplayListImageFilter, Issue108433) {
659 ASSERT_EQ(dl_compose.map_device_bounds(input_bounds,
DlMatrix(), dl_bounds),
661 ASSERT_EQ(dl_bounds, expected_bounds);
664TEST(DisplayListImageFilter, ColorFilterConstructor) {
669TEST(DisplayListImageFilter, ColorFilterShared) {
673 ASSERT_EQ(*filter.
shared(), filter);
676TEST(DisplayListImageFilter, ColorFilterAsColorFilter) {
688 ASSERT_EQ(*filter.
color_filter().get(), dl_color_filter);
691TEST(DisplayListImageFilter, ColorFilterEquals) {
701TEST(DisplayListImageFilter, ColorFilterWithLocalMatrixEquals) {
713TEST(DisplayListImageFilter, ColorFilterNotEquals) {
727TEST(DisplayListImageFilter, ColorFilterBounds) {
731 TestBounds(filter, input_bounds, input_bounds);
734TEST(DisplayListImageFilter, ColorFilterModifiesTransparencyBounds) {
741TEST(DisplayListImageFilter, LocalImageFilterBounds) {
746 std::vector<sk_sp<SkImageFilter>> sk_filters{
747 SkImageFilters::Blur(5.0, 6.0, SkTileMode::kRepeat,
nullptr),
748 SkImageFilters::ColorFilter(
749 SkColorFilters::Blend(SK_ColorRED, SkBlendMode::kSrcOver),
nullptr),
750 SkImageFilters::Dilate(5.0, 10.0,
nullptr),
751 SkImageFilters::MatrixTransform(
ToSkMatrix(filter_matrix),
752 SkSamplingOptions(SkFilterMode::kLinear),
754 SkImageFilters::Compose(
755 SkImageFilters::Blur(5.0, 6.0, SkTileMode::kRepeat,
nullptr),
756 SkImageFilters::ColorFilter(
757 SkColorFilters::Blend(SK_ColorRED, SkBlendMode::kSrcOver),
761 std::vector<std::shared_ptr<DlImageFilter>> dl_filters{
771 auto persp = SkMatrix::I();
772 persp.setPerspY(0.001);
773 std::vector<SkMatrix> sk_matrices = {
774 SkMatrix::Translate(10.0, 10.0),
775 SkMatrix::Scale(2.0, 2.0).preTranslate(10.0, 10.0),
776 SkMatrix::RotateDeg(45).preTranslate(5.0, 5.0),
778 std::vector<DlMatrix> dl_matrices = {
783 std::vector<SkMatrix> sk_bounds_matrices{
784 SkMatrix::Translate(5.0, 10.0),
785 SkMatrix::Scale(2.0, 2.0),
787 std::vector<DlMatrix> dl_bounds_matrices{
792 for (
unsigned j = 0; j < dl_matrices.size(); j++) {
799 EXPECT_EQ(input_bounds, output_bounds);
801 for (
unsigned k = 0; k < dl_bounds_matrices.size(); k++) {
802 auto& bounds_matrix = dl_bounds_matrices[k];
809 EXPECT_EQ(input_bounds, output_bounds);
817 EXPECT_EQ(input_bounds, output_bounds);
822 for (
unsigned i = 0;
i < sk_filters.size();
i++) {
823 for (
unsigned j = 0; j < dl_matrices.size(); j++) {
824 for (
unsigned k = 0; k < dl_bounds_matrices.size(); k++) {
825 auto desc =
"filter " + std::to_string(
i + 1)
826 +
", filter matrix " + std::to_string(j + 1)
827 +
", bounds matrix " + std::to_string(k + 1);
828 auto sk_local_filter =
829 sk_filters[
i]->makeWithLocalMatrix(sk_matrices[j]);
830 auto dl_local_filter =
831 dl_filters[
i]->makeWithLocalMatrix(dl_matrices[j]);
832 if (!sk_local_filter || !dl_local_filter) {
837 ASSERT_TRUE(sk_local_filter || !dl_local_filter) << desc;
841 auto input_bounds = SkIRect::MakeLTRB(20, 20, 80, 80);
844 sk_rect = sk_local_filter->filterBounds(
845 input_bounds, sk_bounds_matrices[k],
846 SkImageFilter::MapDirection::kForward_MapDirection);
847 if (dl_local_filter->map_device_bounds(
848 ToDlIRect(input_bounds), dl_bounds_matrices[k], dl_rect)) {
851 ASSERT_TRUE(dl_local_filter->modifies_transparent_black()) << desc;
852 ASSERT_FALSE(sk_local_filter->canComputeFastBounds()) << desc;
861 if (
i == 2 ||
i == 3) {
864 auto outset_bounds = SkIRect::MakeLTRB(20, 20, 80, 80);
867 sk_rect = sk_local_filter->filterBounds(
868 outset_bounds, sk_bounds_matrices[k],
869 SkImageFilter::MapDirection::kReverse_MapDirection);
870 if (dl_local_filter->get_input_device_bounds(
871 ToDlIRect(outset_bounds), dl_bounds_matrices[k], dl_rect)) {
874 ASSERT_TRUE(dl_local_filter->modifies_transparent_black());
875 ASSERT_FALSE(sk_local_filter->canComputeFastBounds());
883TEST(DisplayListImageFilter, RuntimeEffectEquality) {
885 std::make_shared<std::vector<uint8_t>>());
887 std::make_shared<std::vector<uint8_t>>());
889 EXPECT_EQ(filter_a, filter_b);
892 nullptr, {
nullptr}, std::make_shared<std::vector<uint8_t>>(1));
894 EXPECT_NE(filter_a, filter_c);
897TEST(DisplayListImageFilter, RuntimeEffectEqualityWithSamplers) {
904 std::make_shared<std::vector<uint8_t>>());
906 std::make_shared<std::vector<uint8_t>>());
908 EXPECT_EQ(filter_a, filter_b);
911 std::make_shared<std::vector<uint8_t>>());
913 EXPECT_NE(filter_a, filter_c);
916TEST(DisplayListImageFilter, RuntimeEffectMapDeviceBounds) {
918 std::make_shared<std::vector<uint8_t>>());
926 EXPECT_NE(result,
nullptr);
927 EXPECT_EQ(result, &output_bounds);
928 EXPECT_EQ(output_bounds, input_bounds);
931TEST(DisplayListImageFilter, RuntimeEffectMapInputBounds) {
933 std::make_shared<std::vector<uint8_t>>());
940 EXPECT_NE(result,
nullptr);
941 EXPECT_EQ(result, &output_bounds);
942 EXPECT_EQ(output_bounds, input_bounds);
945TEST(DisplayListImageFilter, RuntimeEffectGetInputDeviceBounds) {
947 std::make_shared<std::vector<uint8_t>>());
956 EXPECT_NE(result,
nullptr);
957 EXPECT_EQ(result, &input_bounds);
958 EXPECT_EQ(output_bounds, input_bounds);
961TEST(DisplayListImageFilter, RuntimeEffectModifiesTransparentBlack) {
963 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)