5#include "flutter/display_list/dl_blend_mode.h"
6#include "flutter/display_list/dl_color.h"
7#include "flutter/display_list/dl_sampling_options.h"
8#include "flutter/display_list/dl_tile_mode.h"
9#include "flutter/display_list/effects/dl_color_filter.h"
10#include "flutter/display_list/effects/dl_image_filter.h"
11#include "flutter/display_list/testing/dl_test_equality.h"
12#include "flutter/display_list/utils/dl_comparable.h"
13#include "gtest/gtest.h"
36 return (
p.fX >=
rect.fLeft - 1
E-9 &&
37 p.fX <=
rect.fRight + 1
E-9 &&
38 p.fY >=
rect.fTop - 1
E-9 &&
39 p.fY <=
rect.fBottom + 1
E-9);
66 const SkRect& sourceBounds,
67 const SkPoint expectedLocalOutputQuad[4]) {
68 SkRect device_input_bounds =
matrix.mapRect(sourceBounds);
69 SkPoint expected_output_quad[4];
70 matrix.mapPoints(expected_output_quad, expectedLocalOutputQuad, 4);
74 device_filter_ibounds),
75 &device_filter_ibounds);
80 reverse_input_ibounds),
81 &reverse_input_ibounds);
87 const SkRect& localInputBounds) {
88 SkIRect device_input_bounds =
matrix.mapRect(localInputBounds).roundOut();
90 SkRect local_filter_bounds;
93 ASSERT_EQ(local_filter_bounds, localInputBounds);
97 device_filter_ibounds),
99 ASSERT_EQ(device_filter_ibounds, device_input_bounds);
103 reverse_input_ibounds),
105 ASSERT_EQ(reverse_input_ibounds, device_input_bounds);
117 const SkRect& sourceBounds,
118 const SkPoint expectedLocalOutputQuad[4]) {
119 SkRect local_filter_bounds;
121 &local_filter_bounds);
125 for (
int skew = 0; skew < 8; skew++) {
126 for (
int degrees = 0; degrees <= 360; degrees += 15) {
129 matrix.postSkew(skew / 8.0, skew / 8.0);
130 matrix.postRotate(degrees);
131 ASSERT_TRUE(
matrix.invert(
nullptr));
133 expectedLocalOutputQuad);
136 ASSERT_TRUE(
matrix.invert(
nullptr));
138 expectedLocalOutputQuad);
145 const SkRect& sourceBounds,
146 const SkRect& expectedLocalOutputBounds) {
147 SkPoint expected_local_output_quad[4];
148 expectedLocalOutputBounds.
toQuad(expected_local_output_quad);
149 TestBounds(filter, sourceBounds, expected_local_output_quad);
152TEST(DisplayListImageFilter, BlurConstructor) {
156TEST(DisplayListImageFilter, BlurShared) {
159 ASSERT_NE(filter.
shared().get(), &filter);
160 ASSERT_EQ(*filter.
shared(), filter);
163TEST(DisplayListImageFilter, BlurAsBlur) {
166 ASSERT_NE(filter.
asBlur(),
nullptr);
167 ASSERT_EQ(filter.
asBlur(), &filter);
170TEST(DisplayListImageFilter, BlurContents) {
173 ASSERT_EQ(filter.
sigma_x(), 5.0);
174 ASSERT_EQ(filter.
sigma_y(), 6.0);
178TEST(DisplayListImageFilter, BlurEquals) {
185TEST(DisplayListImageFilter, BlurWithLocalMatrixEquals) {
194TEST(DisplayListImageFilter, BlurNotEquals) {
205TEST(DisplayListImageFilter, BlurBounds) {
209 TestBounds(filter, input_bounds, expected_output_bounds);
212TEST(DisplayListImageFilter, BlurZeroSigma) {
213 std::shared_ptr<DlImageFilter> filter =
215 ASSERT_EQ(filter,
nullptr);
217 ASSERT_EQ(filter,
nullptr);
219 ASSERT_EQ(filter,
nullptr);
222 ASSERT_EQ(filter,
nullptr);
224 ASSERT_NE(filter,
nullptr);
226 ASSERT_NE(filter,
nullptr);
229TEST(DisplayListImageFilter, DilateConstructor) {
233TEST(DisplayListImageFilter, DilateShared) {
236 ASSERT_NE(filter.
shared().get(), &filter);
237 ASSERT_EQ(*filter.
shared(), filter);
240TEST(DisplayListImageFilter, DilateAsDilate) {
243 ASSERT_NE(filter.
asDilate(),
nullptr);
244 ASSERT_EQ(filter.
asDilate(), &filter);
247TEST(DisplayListImageFilter, DilateContents) {
254TEST(DisplayListImageFilter, DilateEquals) {
261TEST(DisplayListImageFilter, DilateWithLocalMatrixEquals) {
270TEST(DisplayListImageFilter, DilateNotEquals) {
279TEST(DisplayListImageFilter, DilateBounds) {
283 TestBounds(filter, input_bounds, expected_output_bounds);
286TEST(DisplayListImageFilter, ErodeConstructor) {
290TEST(DisplayListImageFilter, ErodeShared) {
293 ASSERT_NE(filter.
shared().get(), &filter);
294 ASSERT_EQ(*filter.
shared(), filter);
297TEST(DisplayListImageFilter, ErodeAsErode) {
300 ASSERT_NE(filter.
asErode(),
nullptr);
301 ASSERT_EQ(filter.
asErode(), &filter);
304TEST(DisplayListImageFilter, ErodeContents) {
311TEST(DisplayListImageFilter, ErodeEquals) {
318TEST(DisplayListImageFilter, ErodeWithLocalMatrixEquals) {
327TEST(DisplayListImageFilter, ErodeNotEquals) {
336TEST(DisplayListImageFilter, ErodeBounds) {
340 TestBounds(filter, input_bounds, expected_output_bounds);
343TEST(DisplayListImageFilter, MatrixConstructor) {
350TEST(DisplayListImageFilter, MatrixShared) {
356 ASSERT_NE(filter.
shared().get(), &filter);
357 ASSERT_EQ(*filter.
shared(), filter);
360TEST(DisplayListImageFilter, MatrixAsMatrix) {
366 ASSERT_NE(filter.
asMatrix(),
nullptr);
367 ASSERT_EQ(filter.
asMatrix(), &filter);
370TEST(DisplayListImageFilter, MatrixContents) {
380TEST(DisplayListImageFilter, MatrixEquals) {
390TEST(DisplayListImageFilter, MatrixWithLocalMatrixEquals) {
402TEST(DisplayListImageFilter, MatrixNotEquals) {
417TEST(DisplayListImageFilter, MatrixBounds) {
422 ASSERT_TRUE(
matrix.invert(&inverse));
425 SkPoint expectedOutputQuad[4] = {
431 TestBounds(filter, input_bounds, expectedOutputQuad);
434TEST(DisplayListImageFilter, ComposeConstructor) {
443TEST(DisplayListImageFilter, ComposeShared) {
451 ASSERT_NE(filter.
shared().get(), &filter);
452 ASSERT_EQ(*filter.
shared(), filter);
455TEST(DisplayListImageFilter, ComposeAsCompose) {
467TEST(DisplayListImageFilter, ComposeContents) {
475 ASSERT_EQ(*filter.
outer().get(), outer);
476 ASSERT_EQ(*filter.
inner().get(), inner);
479TEST(DisplayListImageFilter, ComposeEquals) {
497TEST(DisplayListImageFilter, ComposeWithLocalMatrixEquals) {
517TEST(DisplayListImageFilter, ComposeNotEquals) {
538TEST(DisplayListImageFilter, ComposeBounds) {
543 SkRect expected_output_bounds =
545 TestBounds(filter, input_bounds, expected_output_bounds);
549 const SkRect& sourceBounds,
550 const SkRect& expectedOutputBounds,
551 const SkRect& expectedInputBounds) {
554 EXPECT_EQ(
bounds, expectedOutputBounds);
560 EXPECT_EQ(ibounds, expectedOutputBounds.
roundOut());
565 EXPECT_EQ(ibounds, expectedInputBounds.
roundOut());
568TEST(DisplayListImageFilter, ComposeBoundsWithUnboundedInner) {
580TEST(DisplayListImageFilter, ComposeBoundsWithUnboundedOuter) {
592TEST(DisplayListImageFilter, ComposeBoundsWithUnboundedInnerAndOuter) {
594 auto expected_bounds = input_bounds;
606TEST(DisplayListImageFilter, Issue108433) {
617 dl_compose.map_device_bounds(input_bounds,
SkMatrix::I(), dl_bounds),
619 ASSERT_EQ(dl_bounds, expected_bounds);
622TEST(DisplayListImageFilter, ColorFilterConstructor) {
627TEST(DisplayListImageFilter, ColorFilterShared) {
631 ASSERT_EQ(*filter.
shared(), filter);
634TEST(DisplayListImageFilter, ColorFilterAsColorFilter) {
642TEST(DisplayListImageFilter, ColorFilterContents) {
646 ASSERT_EQ(*filter.
color_filter().get(), dl_color_filter);
649TEST(DisplayListImageFilter, ColorFilterEquals) {
659TEST(DisplayListImageFilter, ColorFilterWithLocalMatrixEquals) {
671TEST(DisplayListImageFilter, ColorFilterNotEquals) {
685TEST(DisplayListImageFilter, ColorFilterBounds) {
689 TestBounds(filter, input_bounds, input_bounds);
692TEST(DisplayListImageFilter, ColorFilterModifiesTransparencyBounds) {
699TEST(DisplayListImageFilter, LocalImageFilterBounds) {
703 std::vector<sk_sp<SkImageFilter>> sk_filters{
717 std::vector<std::shared_ptr<DlImageFilter>> dl_filters{
719 std::make_shared<DlColorFilterImageFilter>(dl_color_filter.
shared()),
720 std::make_shared<DlDilateImageFilter>(5, 10),
721 std::make_shared<DlMatrixImageFilter>(filter_matrix,
723 std::make_shared<DlComposeImageFilter>(
725 std::make_shared<DlColorFilterImageFilter>(
726 dl_color_filter.
shared()))};
729 persp.setPerspY(0.001);
730 std::vector<SkMatrix> matrices = {
737 for (
unsigned j = 0; j < matrices.size(); j++) {
744 EXPECT_EQ(input_bounds, output_bounds);
746 for (
unsigned k = 0; k < bounds_matrices.size(); k++) {
747 auto& bounds_matrix = bounds_matrices[k];
754 EXPECT_EQ(input_bounds, output_bounds);
762 EXPECT_EQ(input_bounds, output_bounds);
767 for (
unsigned i = 0;
i < sk_filters.size();
i++) {
768 for (
unsigned j = 0; j < matrices.size(); j++) {
769 for (
unsigned k = 0; k < bounds_matrices.size(); k++) {
773 auto&
m = matrices[j];
774 auto& bounds_matrix = bounds_matrices[k];
775 auto sk_local_filter = sk_filters[
i]->makeWithLocalMatrix(
m);
776 auto dl_local_filter = dl_filters[
i]->makeWithLocalMatrix(
m);
777 if (!sk_local_filter || !dl_local_filter) {
782 ASSERT_TRUE(sk_local_filter || !dl_local_filter) <<
desc;
788 sk_rect = sk_local_filter->filterBounds(
789 input_bounds, bounds_matrix,
790 SkImageFilter::MapDirection::kForward_MapDirection);
791 if (dl_local_filter->map_device_bounds(input_bounds, bounds_matrix,
795 ASSERT_TRUE(dl_local_filter->modifies_transparent_black()) <<
desc;
796 ASSERT_FALSE(sk_local_filter->canComputeFastBounds()) <<
desc;
805 if (
i == 2 ||
i == 3) {
810 sk_rect = sk_local_filter->filterBounds(
811 outset_bounds, bounds_matrix,
812 SkImageFilter::MapDirection::kReverse_MapDirection);
813 if (dl_local_filter->get_input_device_bounds(
814 outset_bounds, bounds_matrix, dl_rect)) {
817 ASSERT_TRUE(dl_local_filter->modifies_transparent_black());
818 ASSERT_FALSE(sk_local_filter->canComputeFastBounds());
@ kSrcOver
r = s + (1-sa)*d
constexpr SkColor SK_ColorRED
static sk_sp< SkImage > color_filter(const SkImage *image, SkColorFilter *colorFilter)
static sk_sp< SkColorFilter > Blend(const SkColor4f &c, sk_sp< SkColorSpace >, SkBlendMode mode)
static sk_sp< SkImageFilter > ColorFilter(sk_sp< SkColorFilter > cf, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Blur(SkScalar sigmaX, SkScalar sigmaY, SkTileMode tileMode, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Compose(sk_sp< SkImageFilter > outer, sk_sp< SkImageFilter > inner)
static sk_sp< SkImageFilter > MatrixTransform(const SkMatrix &matrix, const SkSamplingOptions &sampling, sk_sp< SkImageFilter > input)
static sk_sp< SkImageFilter > Dilate(SkScalar radiusX, SkScalar radiusY, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static SkMatrix Scale(SkScalar sx, SkScalar sy)
static SkMatrix RotateDeg(SkScalar deg)
static SkMatrix Translate(SkScalar dx, SkScalar dy)
static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar pers0, SkScalar pers1, SkScalar pers2)
static const SkMatrix & I()
SkMatrix & preTranslate(SkScalar dx, SkScalar dy)
std::shared_ptr< DlColorFilter > shared() const override
std::shared_ptr< DlImageFilter > shared() const override
static std::shared_ptr< DlImageFilter > Make(SkScalar sigma_x, SkScalar sigma_y, DlTileMode tile_mode)
const DlBlurImageFilter * asBlur() const override
DlTileMode tile_mode() const
const std::shared_ptr< const DlColorFilter > color_filter() const
std::shared_ptr< DlImageFilter > makeWithLocalMatrix(const SkMatrix &matrix) const override
const DlColorFilterImageFilter * asColorFilter() const override
std::shared_ptr< DlImageFilter > shared() const override
std::shared_ptr< DlImageFilter > shared() const override
const DlComposeImageFilter * asCompose() const override
std::shared_ptr< const DlImageFilter > outer() const
std::shared_ptr< const DlImageFilter > inner() const
SkScalar radius_y() const
SkScalar radius_x() const
const DlDilateImageFilter * asDilate() const override
std::shared_ptr< DlImageFilter > shared() const override
const DlErodeImageFilter * asErode() const override
std::shared_ptr< DlImageFilter > shared() const override
SkScalar radius_y() const
SkScalar radius_x() const
virtual SkIRect * map_device_bounds(const SkIRect &input_bounds, const SkMatrix &ctm, SkIRect &output_bounds) const =0
virtual SkRect * map_local_bounds(const SkRect &input_bounds, SkRect &output_bounds) const =0
virtual SkIRect * get_input_device_bounds(const SkIRect &output_bounds, const SkMatrix &ctm, SkIRect &input_bounds) const =0
virtual std::shared_ptr< DlImageFilter > makeWithLocalMatrix(const SkMatrix &matrix) const
SkIRect * map_device_bounds(const SkIRect &input_bounds, const SkMatrix &ctm, SkIRect &output_bounds) const override
SkRect * map_local_bounds(const SkRect &input_bounds, SkRect &output_bounds) const override
SkIRect * get_input_device_bounds(const SkIRect &output_bounds, const SkMatrix &ctm, SkIRect &input_bounds) const override
const DlMatrixImageFilter * asMatrix() const override
std::shared_ptr< DlImageFilter > shared() const override
const SkMatrix & matrix() const
DlImageSampling sampling() const
unsigned useCenter Optional< SkMatrix > matrix
Optional< SkRect > bounds
sk_sp< SkBlender > blender SkRect rect
static void TestInvalidBounds(const DlImageFilter &filter, const SkMatrix &matrix, const SkRect &localInputBounds)
static void TestBoundsWithMatrix(const DlImageFilter &filter, const SkMatrix &matrix, const SkRect &sourceBounds, const SkPoint expectedLocalOutputQuad[4])
static void TestUnboundedBounds(DlImageFilter &filter, const SkRect &sourceBounds, const SkRect &expectedOutputBounds, const SkRect &expectedInputBounds)
static bool containsInclusive(const SkRect rect, const SkPoint p)
static void TestBounds(const DlImageFilter &filter, const SkRect &sourceBounds, const SkPoint expectedLocalOutputQuad[4])
static void TestNotEquals(T &source1, T &source2, const std::string &label)
static void TestEquals(T &source1, T &source2)
TEST(DisplayListComplexity, EmptyDisplayList)
@ kLighten
rc = s + d - min(s*da, d*sa), ra = kSrcOver
@ kSrcOver
r = s + (1-sa)*d
@ kDarken
rc = s + d - max(s*da, d*sa), ra = kSrcOver
SkSamplingOptions(SkFilterMode::kLinear))
static SkString to_string(int n)
static constexpr SkIRect MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
static SkRect Make(const SkISize &size)
void toQuad(SkPoint quad[4]) const
SkRect makeOutset(float dx, float dy) const
SkRect makeInset(float dx, float dy) const
void roundOut(SkIRect *dst) const
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
static constexpr DlColor kBlue()
static constexpr DlColor kRed()