[M108 Migration][Loading Performance] Introduce |BeginMainFrame| throttling
[platform/framework/web/chromium-efl.git] / cc / paint / filter_operations_unittest.cc
1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stddef.h>
6 #include <limits>
7 #include <string>
8 #include <utility>
9
10 #include "cc/paint/filter_operation.h"
11 #include "cc/paint/filter_operations.h"
12
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "ui/gfx/geometry/point.h"
15 #include "ui/gfx/geometry/rect.h"
16
17 namespace cc {
18 namespace {
19
20 TEST(FilterOperationsTest, MapRectBlur) {
21   FilterOperations ops;
22   ops.Append(FilterOperation::CreateBlurFilter(20));
23   EXPECT_EQ(gfx::Rect(-60, -60, 130, 130),
24             ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I()));
25   EXPECT_EQ(gfx::Rect(-120, -120, 260, 260),
26             ops.MapRect(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2)));
27   EXPECT_EQ(gfx::Rect(-60, -70, 130, 130),
28             ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1)));
29 }
30
31 TEST(FilterOperationsTest, MapRectBlurOverflow) {
32   // Passes if float-cast-overflow does not occur in ubsan builds.
33   // The blur spread exceeds INT_MAX.
34   FilterOperations ops;
35   ops.Append(FilterOperation::CreateBlurFilter(2e9f));
36   ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I());
37 }
38
39 TEST(FilterOperationsTest, MapRectReverseBlur) {
40   FilterOperations ops;
41   ops.Append(FilterOperation::CreateBlurFilter(20));
42   EXPECT_EQ(gfx::Rect(60, 60, 30, 30),
43             ops.MapRectReverse(gfx::Rect(0, 0, 150, 150), SkMatrix::I()));
44   EXPECT_EQ(
45       gfx::Rect(120, 120, 60, 60),
46       ops.MapRectReverse(gfx::Rect(0, 0, 300, 300), SkMatrix::Scale(2, 2)));
47   EXPECT_EQ(
48       gfx::Rect(60, 50, 30, 30),
49       ops.MapRectReverse(gfx::Rect(0, -10, 150, 150), SkMatrix::Scale(1, -1)));
50 }
51
52 TEST(FilterOperationsTest, MapRectDropShadowReferenceFilter) {
53   FilterOperations ops;
54   ops.Append(
55       FilterOperation::CreateReferenceFilter(sk_make_sp<DropShadowPaintFilter>(
56           SkIntToScalar(3), SkIntToScalar(8), SkIntToScalar(4),
57           SkIntToScalar(9), SkColors::kBlack,
58           DropShadowPaintFilter::ShadowMode::kDrawShadowAndForeground,
59           nullptr)));
60   EXPECT_EQ(gfx::Rect(-9, -19, 34, 64),
61             ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I()));
62   EXPECT_EQ(gfx::Rect(-18, -38, 68, 128),
63             ops.MapRect(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2)));
64   EXPECT_EQ(gfx::Rect(-9, -45, 34, 64),
65             ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1)));
66 }
67
68 TEST(FilterOperationsTest, MapRectReverseDropShadowReferenceFilter) {
69   FilterOperations ops;
70   ops.Append(
71       FilterOperation::CreateReferenceFilter(sk_make_sp<DropShadowPaintFilter>(
72           SkIntToScalar(3), SkIntToScalar(8), SkIntToScalar(4),
73           SkIntToScalar(9), SkColors::kBlack,
74           DropShadowPaintFilter::ShadowMode::kDrawShadowAndForeground,
75           nullptr)));
76   EXPECT_EQ(gfx::Rect(-15, -35, 34, 64),
77             ops.MapRectReverse(gfx::Rect(0, 0, 10, 10), SkMatrix::I()));
78   EXPECT_EQ(gfx::Rect(-30, -70, 68, 128),
79             ops.MapRectReverse(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2)));
80   EXPECT_EQ(
81       gfx::Rect(-15, -29, 34, 64),
82       ops.MapRectReverse(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1)));
83 }
84
85 TEST(FilterOperationsTest, MapRectOffsetReferenceFilter) {
86   sk_sp<PaintFilter> filter = sk_make_sp<OffsetPaintFilter>(30, 40, nullptr);
87   FilterOperations ops;
88   ops.Append(FilterOperation::CreateReferenceFilter(std::move(filter)));
89   EXPECT_EQ(gfx::Rect(30, 40, 10, 10),
90             ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I()));
91   EXPECT_EQ(gfx::Rect(60, 80, 20, 20),
92             ops.MapRect(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2)));
93   EXPECT_EQ(gfx::Rect(30, -50, 10, 10),
94             ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1)));
95 }
96
97 TEST(FilterOperationsTest, MapRectReverseOffsetReferenceFilter) {
98   sk_sp<PaintFilter> filter = sk_make_sp<OffsetPaintFilter>(30, 40, nullptr);
99   FilterOperations ops;
100   ops.Append(FilterOperation::CreateReferenceFilter(std::move(filter)));
101   EXPECT_EQ(gfx::Rect(-30, -40, 10, 10),
102             ops.MapRectReverse(gfx::Rect(0, 0, 10, 10), SkMatrix::I()));
103   EXPECT_EQ(gfx::Rect(-60, -80, 20, 20),
104             ops.MapRectReverse(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2)));
105   EXPECT_EQ(
106       gfx::Rect(-30, 30, 10, 10),
107       ops.MapRectReverse(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1)));
108 }
109
110 TEST(FilterOperationsTest, MapRectCombineNonCommutative) {
111   // Offsets by 100px in each axis, then scales the resulting image by 2.
112   FilterOperations ops;
113   ops.Append(FilterOperation::CreateReferenceFilter(
114       sk_make_sp<OffsetPaintFilter>(100, 100, nullptr)));
115   SkMatrix scaleMatrix;
116   scaleMatrix.setScale(2, 2);
117   ops.Append(
118       FilterOperation::CreateReferenceFilter(sk_make_sp<MatrixPaintFilter>(
119           scaleMatrix, PaintFlags::FilterQuality::kNone, nullptr)));
120
121   EXPECT_EQ(gfx::Rect(200, 200, 20, 20),
122             ops.MapRect(gfx::Rect(10, 10), SkMatrix::I()));
123   EXPECT_EQ(gfx::Rect(400, 400, 40, 40),
124             ops.MapRect(gfx::Rect(20, 20), SkMatrix::Scale(2, 2)));
125   EXPECT_EQ(gfx::Rect(200, -220, 20, 20),
126             ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1)));
127 }
128
129 TEST(FilterOperationsTest, MapRectReverseCombineNonCommutative) {
130   // Offsets by 100px in each axis, then scales the resulting image by 2.
131   FilterOperations ops;
132   ops.Append(FilterOperation::CreateReferenceFilter(
133       sk_make_sp<OffsetPaintFilter>(100, 100, nullptr)));
134   SkMatrix scaleMatrix;
135   scaleMatrix.setScale(2, 2);
136   ops.Append(
137       FilterOperation::CreateReferenceFilter(sk_make_sp<MatrixPaintFilter>(
138           scaleMatrix, PaintFlags::FilterQuality::kNone, nullptr)));
139
140   EXPECT_EQ(gfx::Rect(10, 10),
141             ops.MapRectReverse(gfx::Rect(200, 200, 20, 20), SkMatrix::I()));
142   EXPECT_EQ(gfx::Rect(20, 20), ops.MapRectReverse(gfx::Rect(400, 400, 40, 40),
143                                                   SkMatrix::Scale(2, 2)));
144   EXPECT_EQ(
145       gfx::Rect(0, -10, 10, 10),
146       ops.MapRectReverse(gfx::Rect(200, -220, 20, 20), SkMatrix::Scale(1, -1)));
147 }
148
149 TEST(FilterOperationsTest, MapRectNullReferenceFilter) {
150   FilterOperations ops;
151   ops.Append(FilterOperation::CreateReferenceFilter(nullptr));
152   EXPECT_EQ(gfx::Rect(0, 0, 10, 10),
153             ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I()));
154   EXPECT_EQ(gfx::Rect(0, 0, 20, 20),
155             ops.MapRect(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2)));
156   EXPECT_EQ(gfx::Rect(0, -10, 10, 10),
157             ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1)));
158 }
159
160 TEST(FilterOperationsTest, MapRectReverseNullReferenceFilter) {
161   FilterOperations ops;
162   ops.Append(FilterOperation::CreateReferenceFilter(nullptr));
163   EXPECT_EQ(gfx::Rect(0, 0, 10, 10),
164             ops.MapRectReverse(gfx::Rect(0, 0, 10, 10), SkMatrix::I()));
165   EXPECT_EQ(gfx::Rect(0, 0, 20, 20),
166             ops.MapRectReverse(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2)));
167   EXPECT_EQ(
168       gfx::Rect(0, -10, 10, 10),
169       ops.MapRectReverse(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1)));
170 }
171
172 TEST(FilterOperationsTest, MapRectDropShadow) {
173   FilterOperations ops;
174   ops.Append(FilterOperation::CreateDropShadowFilter(gfx::Point(3, 8), 20,
175                                                      SkColors::kTransparent));
176   EXPECT_EQ(gfx::Rect(-57, -52, 130, 130),
177             ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I()));
178   EXPECT_EQ(gfx::Rect(-114, -104, 260, 260),
179             ops.MapRect(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2)));
180   EXPECT_EQ(gfx::Rect(-57, -78, 130, 130),
181             ops.MapRect(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1)));
182 }
183
184 TEST(FilterOperationsTest, MapRectReverseDropShadow) {
185   FilterOperations ops;
186   ops.Append(FilterOperation::CreateDropShadowFilter(gfx::Point(3, 8), 20,
187                                                      SkColors::kTransparent));
188   EXPECT_EQ(gfx::Rect(-63, -68, 130, 130),
189             ops.MapRectReverse(gfx::Rect(0, 0, 10, 10), SkMatrix::I()));
190   EXPECT_EQ(gfx::Rect(-126, -136, 260, 260),
191             ops.MapRectReverse(gfx::Rect(0, 0, 20, 20), SkMatrix::Scale(2, 2)));
192   EXPECT_EQ(
193       gfx::Rect(-63, -62, 130, 130),
194       ops.MapRectReverse(gfx::Rect(0, -10, 10, 10), SkMatrix::Scale(1, -1)));
195 }
196
197 TEST(FilterOperationsTest, MapRectDropShadowDoesNotContract) {
198   // Even with a drop-shadow, the original content is still drawn. Thus the
199   // content bounds are never contracted due to a drop-shadow.
200   FilterOperations ops;
201   ops.Append(FilterOperation::CreateDropShadowFilter(gfx::Point(3, 8), 0,
202                                                      SkColors::kTransparent));
203   EXPECT_EQ(gfx::Rect(0, 0, 13, 18),
204             ops.MapRect(gfx::Rect(0, 0, 10, 10), SkMatrix::I()));
205 }
206
207 TEST(FilterOperationsTest, MapRectReverseDropShadowDoesNotContract) {
208   // Even with a drop-shadow, the original content is still drawn. Thus the
209   // content bounds are never contracted due to a drop-shadow.
210   FilterOperations ops;
211   ops.Append(FilterOperation::CreateDropShadowFilter(gfx::Point(3, 8), 0,
212                                                      SkColors::kTransparent));
213   EXPECT_EQ(gfx::Rect(-3, -8, 13, 18),
214             ops.MapRectReverse(gfx::Rect(0, 0, 10, 10), SkMatrix::I()));
215 }
216
217 TEST(FilterOperationsTest, MapRectTypeConversionDoesNotOverflow) {
218   // Must be bigger than half of the positive range so that the width/height
219   // overflow happens, but small enough that there aren't other issues before
220   // the overflow would happen.
221   SkScalar big_offset =
222       SkFloatToScalar(std::numeric_limits<int>::max()) * 2 / 3;
223
224   FilterOperations ops;
225   ops.Append(
226       FilterOperation::CreateReferenceFilter(sk_make_sp<XfermodePaintFilter>(
227           SkBlendMode::kSrcOver,
228           sk_make_sp<OffsetPaintFilter>(-big_offset, -big_offset, nullptr),
229           sk_make_sp<OffsetPaintFilter>(big_offset, big_offset, nullptr))));
230   gfx::Rect rect = ops.MapRect(gfx::Rect(-10, -10, 20, 20), SkMatrix::I());
231   EXPECT_GT(rect.width(), 0);
232   EXPECT_GT(rect.height(), 0);
233 }
234
235 #define SAVE_RESTORE_AMOUNT(filter_name, filter_type, a)                  \
236   {                                                                       \
237     FilterOperation op = FilterOperation::Create##filter_name##Filter(a); \
238     EXPECT_EQ(FilterOperation::filter_type, op.type());                   \
239     EXPECT_EQ(a, op.amount());                                            \
240                                                                           \
241     FilterOperation op2 = FilterOperation::CreateEmptyFilter();           \
242     op2.set_type(FilterOperation::filter_type);                           \
243                                                                           \
244     EXPECT_NE(a, op2.amount());                                           \
245                                                                           \
246     op2.set_amount(a);                                                    \
247                                                                           \
248     EXPECT_EQ(FilterOperation::filter_type, op2.type());                  \
249     EXPECT_EQ(a, op2.amount());                                           \
250   }
251
252 #define SAVE_RESTORE_OFFSET_AMOUNT_COLOR(filter_name, filter_type, a, b, c) \
253   {                                                                         \
254     FilterOperation op =                                                    \
255         FilterOperation::Create##filter_name##Filter(a, b, c);              \
256     EXPECT_EQ(FilterOperation::filter_type, op.type());                     \
257     EXPECT_EQ(a, op.drop_shadow_offset());                                  \
258     EXPECT_EQ(b, op.amount());                                              \
259     EXPECT_EQ(c, op.drop_shadow_color());                                   \
260                                                                             \
261     FilterOperation op2 = FilterOperation::CreateEmptyFilter();             \
262     op2.set_type(FilterOperation::filter_type);                             \
263                                                                             \
264     EXPECT_NE(a, op2.drop_shadow_offset());                                 \
265     EXPECT_NE(b, op2.amount());                                             \
266     EXPECT_NE(c, op2.drop_shadow_color());                                  \
267                                                                             \
268     op2.set_drop_shadow_offset(a);                                          \
269     op2.set_amount(b);                                                      \
270     op2.set_drop_shadow_color(c);                                           \
271                                                                             \
272     EXPECT_EQ(FilterOperation::filter_type, op2.type());                    \
273     EXPECT_EQ(a, op2.drop_shadow_offset());                                 \
274     EXPECT_EQ(b, op2.amount());                                             \
275     EXPECT_EQ(c, op2.drop_shadow_color());                                  \
276   }
277
278 #define SAVE_RESTORE_MATRIX(filter_name, filter_type, a)                  \
279   {                                                                       \
280     FilterOperation op = FilterOperation::Create##filter_name##Filter(a); \
281     EXPECT_EQ(FilterOperation::filter_type, op.type());                   \
282     for (size_t i = 0; i < 20; ++i)                                       \
283       EXPECT_EQ(a[i], op.matrix()[i]);                                    \
284                                                                           \
285     FilterOperation op2 = FilterOperation::CreateEmptyFilter();           \
286     op2.set_type(FilterOperation::filter_type);                           \
287                                                                           \
288     for (size_t i = 0; i < 20; ++i)                                       \
289       EXPECT_NE(a[i], op2.matrix()[i]);                                   \
290                                                                           \
291     op2.set_matrix(a);                                                    \
292                                                                           \
293     EXPECT_EQ(FilterOperation::filter_type, op2.type());                  \
294     for (size_t i = 0; i < 20; ++i)                                       \
295       EXPECT_EQ(a[i], op.matrix()[i]);                                    \
296   }
297
298 #define SAVE_RESTORE_AMOUNT_INSET(filter_name, filter_type, a, b)            \
299   {                                                                          \
300     FilterOperation op = FilterOperation::Create##filter_name##Filter(a, b); \
301     EXPECT_EQ(FilterOperation::filter_type, op.type());                      \
302     EXPECT_EQ(a, op.amount());                                               \
303     EXPECT_EQ(b, op.zoom_inset());                                           \
304                                                                              \
305     FilterOperation op2 = FilterOperation::CreateEmptyFilter();              \
306     op2.set_type(FilterOperation::filter_type);                              \
307                                                                              \
308     EXPECT_NE(a, op2.amount());                                              \
309     EXPECT_NE(b, op2.zoom_inset());                                          \
310                                                                              \
311     op2.set_amount(a);                                                       \
312     op2.set_zoom_inset(b);                                                   \
313                                                                              \
314     EXPECT_EQ(FilterOperation::filter_type, op2.type());                     \
315     EXPECT_EQ(a, op2.amount());                                              \
316     EXPECT_EQ(b, op2.zoom_inset());                                          \
317   }
318
319 TEST(FilterOperationsTest, SaveAndRestore) {
320   SAVE_RESTORE_AMOUNT(Grayscale, GRAYSCALE, 0.6f);
321   SAVE_RESTORE_AMOUNT(Sepia, SEPIA, 0.6f);
322   SAVE_RESTORE_AMOUNT(Saturate, SATURATE, 0.6f);
323   SAVE_RESTORE_AMOUNT(HueRotate, HUE_ROTATE, 0.6f);
324   SAVE_RESTORE_AMOUNT(Invert, INVERT, 0.6f);
325   SAVE_RESTORE_AMOUNT(Brightness, BRIGHTNESS, 0.6f);
326   SAVE_RESTORE_AMOUNT(Contrast, CONTRAST, 0.6f);
327   SAVE_RESTORE_AMOUNT(Opacity, OPACITY, 0.6f);
328   SAVE_RESTORE_AMOUNT(Blur, BLUR, 0.6f);
329   SAVE_RESTORE_AMOUNT(SaturatingBrightness, SATURATING_BRIGHTNESS, 0.6f);
330   SAVE_RESTORE_OFFSET_AMOUNT_COLOR(DropShadow, DROP_SHADOW, gfx::Point(3, 4),
331                                    0.4f, SkColors::kYellow);
332
333   FilterOperation::Matrix matrix = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10,
334                                     11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
335   SAVE_RESTORE_MATRIX(ColorMatrix, COLOR_MATRIX, matrix);
336
337   SAVE_RESTORE_AMOUNT_INSET(Zoom, ZOOM, 0.5f, 32);
338 }
339
340 TEST(FilterOperationsTest, BlendGrayscaleFilters) {
341   FilterOperation from = FilterOperation::CreateGrayscaleFilter(0.25f);
342   FilterOperation to = FilterOperation::CreateGrayscaleFilter(0.75f);
343
344   FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
345   FilterOperation expected = FilterOperation::CreateGrayscaleFilter(0.f);
346   EXPECT_EQ(expected, blended);
347
348   blended = FilterOperation::Blend(&from, &to, 0.75);
349   expected = FilterOperation::CreateGrayscaleFilter(0.625f);
350   EXPECT_EQ(expected, blended);
351
352   blended = FilterOperation::Blend(&from, &to, 1.8);
353   expected = FilterOperation::CreateGrayscaleFilter(1.f);
354   EXPECT_EQ(expected, blended);
355 }
356
357 TEST(FilterOperationsTest, BlendGrayscaleWithNull) {
358   FilterOperation filter = FilterOperation::CreateGrayscaleFilter(1.f);
359
360   FilterOperation blended = FilterOperation::Blend(&filter, nullptr, 0.25);
361   FilterOperation expected = FilterOperation::CreateGrayscaleFilter(0.75f);
362   EXPECT_EQ(expected, blended);
363
364   blended = FilterOperation::Blend(nullptr, &filter, 0.25);
365   expected = FilterOperation::CreateGrayscaleFilter(0.25f);
366   EXPECT_EQ(expected, blended);
367 }
368
369 TEST(FilterOperationsTest, BlendSepiaFilters) {
370   FilterOperation from = FilterOperation::CreateSepiaFilter(0.25f);
371   FilterOperation to = FilterOperation::CreateSepiaFilter(0.75f);
372
373   FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
374   FilterOperation expected = FilterOperation::CreateSepiaFilter(0.f);
375   EXPECT_EQ(expected, blended);
376
377   blended = FilterOperation::Blend(&from, &to, 0.75);
378   expected = FilterOperation::CreateSepiaFilter(0.625f);
379   EXPECT_EQ(expected, blended);
380
381   blended = FilterOperation::Blend(&from, &to, 1.8);
382   expected = FilterOperation::CreateSepiaFilter(1.f);
383   EXPECT_EQ(expected, blended);
384 }
385
386 TEST(FilterOperationsTest, BlendSepiaWithNull) {
387   FilterOperation filter = FilterOperation::CreateSepiaFilter(1.f);
388
389   FilterOperation blended = FilterOperation::Blend(&filter, nullptr, 0.25);
390   FilterOperation expected = FilterOperation::CreateSepiaFilter(0.75f);
391   EXPECT_EQ(expected, blended);
392
393   blended = FilterOperation::Blend(nullptr, &filter, 0.25);
394   expected = FilterOperation::CreateSepiaFilter(0.25f);
395   EXPECT_EQ(expected, blended);
396 }
397
398 TEST(FilterOperationsTest, BlendSaturateFilters) {
399   FilterOperation from = FilterOperation::CreateSaturateFilter(0.25f);
400   FilterOperation to = FilterOperation::CreateSaturateFilter(0.75f);
401
402   FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
403   FilterOperation expected = FilterOperation::CreateSaturateFilter(0.f);
404   EXPECT_EQ(expected, blended);
405
406   blended = FilterOperation::Blend(&from, &to, 0.75);
407   expected = FilterOperation::CreateSaturateFilter(0.625f);
408   EXPECT_EQ(expected, blended);
409
410   blended = FilterOperation::Blend(&from, &to, 2.0);
411   expected = FilterOperation::CreateSaturateFilter(1.25f);
412   EXPECT_EQ(expected, blended);
413 }
414
415 TEST(FilterOperationsTest, BlendSaturateWithNull) {
416   FilterOperation filter = FilterOperation::CreateSaturateFilter(0.f);
417
418   FilterOperation blended = FilterOperation::Blend(&filter, nullptr, 0.25);
419   FilterOperation expected = FilterOperation::CreateSaturateFilter(0.25f);
420   EXPECT_EQ(expected, blended);
421
422   blended = FilterOperation::Blend(nullptr, &filter, 0.25);
423   expected = FilterOperation::CreateSaturateFilter(0.75f);
424   EXPECT_EQ(expected, blended);
425 }
426
427 TEST(FilterOperationsTest, BlendHueRotateFilters) {
428   FilterOperation from = FilterOperation::CreateHueRotateFilter(3.f);
429   FilterOperation to = FilterOperation::CreateHueRotateFilter(7.f);
430
431   FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
432   FilterOperation expected = FilterOperation::CreateHueRotateFilter(0.f);
433   EXPECT_EQ(expected, blended);
434
435   blended = FilterOperation::Blend(&from, &to, 0.75);
436   expected = FilterOperation::CreateHueRotateFilter(6.f);
437   EXPECT_EQ(expected, blended);
438
439   blended = FilterOperation::Blend(&from, &to, 1.5);
440   expected = FilterOperation::CreateHueRotateFilter(9.f);
441   EXPECT_EQ(expected, blended);
442 }
443
444 TEST(FilterOperationsTest, BlendHueRotateWithNull) {
445   FilterOperation filter = FilterOperation::CreateHueRotateFilter(1.f);
446
447   FilterOperation blended = FilterOperation::Blend(&filter, nullptr, 0.25);
448   FilterOperation expected = FilterOperation::CreateHueRotateFilter(0.75f);
449   EXPECT_EQ(expected, blended);
450
451   blended = FilterOperation::Blend(nullptr, &filter, 0.25);
452   expected = FilterOperation::CreateHueRotateFilter(0.25f);
453   EXPECT_EQ(expected, blended);
454 }
455
456 TEST(FilterOperationsTest, BlendInvertFilters) {
457   FilterOperation from = FilterOperation::CreateInvertFilter(0.25f);
458   FilterOperation to = FilterOperation::CreateInvertFilter(0.75f);
459
460   FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
461   FilterOperation expected = FilterOperation::CreateInvertFilter(0.f);
462   EXPECT_EQ(expected, blended);
463
464   blended = FilterOperation::Blend(&from, &to, 0.75);
465   expected = FilterOperation::CreateInvertFilter(0.625f);
466   EXPECT_EQ(expected, blended);
467
468   blended = FilterOperation::Blend(&from, &to, 1.8);
469   expected = FilterOperation::CreateInvertFilter(1.f);
470   EXPECT_EQ(expected, blended);
471 }
472
473 TEST(FilterOperationsTest, BlendInvertWithNull) {
474   FilterOperation filter = FilterOperation::CreateInvertFilter(1.f);
475
476   FilterOperation blended = FilterOperation::Blend(&filter, nullptr, 0.25);
477   FilterOperation expected = FilterOperation::CreateInvertFilter(0.75f);
478   EXPECT_EQ(expected, blended);
479
480   blended = FilterOperation::Blend(nullptr, &filter, 0.25);
481   expected = FilterOperation::CreateInvertFilter(0.25f);
482   EXPECT_EQ(expected, blended);
483 }
484
485 TEST(FilterOperationsTest, BlendBrightnessFilters) {
486   FilterOperation from = FilterOperation::CreateBrightnessFilter(3.f);
487   FilterOperation to = FilterOperation::CreateBrightnessFilter(7.f);
488
489   FilterOperation blended = FilterOperation::Blend(&from, &to, -0.9);
490   FilterOperation expected = FilterOperation::CreateBrightnessFilter(0.f);
491   EXPECT_EQ(expected, blended);
492
493   blended = FilterOperation::Blend(&from, &to, 0.75);
494   expected = FilterOperation::CreateBrightnessFilter(6.f);
495   EXPECT_EQ(expected, blended);
496
497   blended = FilterOperation::Blend(&from, &to, 1.5);
498   expected = FilterOperation::CreateBrightnessFilter(9.f);
499   EXPECT_EQ(expected, blended);
500 }
501
502 TEST(FilterOperationsTest, BlendBrightnessWithNull) {
503   FilterOperation filter = FilterOperation::CreateBrightnessFilter(0.f);
504
505   FilterOperation blended = FilterOperation::Blend(&filter, nullptr, 0.25);
506   FilterOperation expected = FilterOperation::CreateBrightnessFilter(0.25f);
507   EXPECT_EQ(expected, blended);
508
509   blended = FilterOperation::Blend(nullptr, &filter, 0.25);
510   expected = FilterOperation::CreateBrightnessFilter(0.75f);
511   EXPECT_EQ(expected, blended);
512 }
513
514 TEST(FilterOperationsTest, BlendContrastFilters) {
515   FilterOperation from = FilterOperation::CreateContrastFilter(3.f);
516   FilterOperation to = FilterOperation::CreateContrastFilter(7.f);
517
518   FilterOperation blended = FilterOperation::Blend(&from, &to, -0.9);
519   FilterOperation expected = FilterOperation::CreateContrastFilter(0.f);
520   EXPECT_EQ(expected, blended);
521
522   blended = FilterOperation::Blend(&from, &to, 0.75);
523   expected = FilterOperation::CreateContrastFilter(6.f);
524   EXPECT_EQ(expected, blended);
525
526   blended = FilterOperation::Blend(&from, &to, 1.5);
527   expected = FilterOperation::CreateContrastFilter(9.f);
528   EXPECT_EQ(expected, blended);
529 }
530
531 TEST(FilterOperationsTest, BlendContrastWithNull) {
532   FilterOperation filter = FilterOperation::CreateContrastFilter(0.f);
533
534   FilterOperation blended = FilterOperation::Blend(&filter, nullptr, 0.25);
535   FilterOperation expected = FilterOperation::CreateContrastFilter(0.25f);
536   EXPECT_EQ(expected, blended);
537
538   blended = FilterOperation::Blend(nullptr, &filter, 0.25);
539   expected = FilterOperation::CreateContrastFilter(0.75f);
540   EXPECT_EQ(expected, blended);
541 }
542
543 TEST(FilterOperationsTest, BlendOpacityFilters) {
544   FilterOperation from = FilterOperation::CreateOpacityFilter(0.25f);
545   FilterOperation to = FilterOperation::CreateOpacityFilter(0.75f);
546
547   FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
548   FilterOperation expected = FilterOperation::CreateOpacityFilter(0.f);
549   EXPECT_EQ(expected, blended);
550
551   blended = FilterOperation::Blend(&from, &to, 0.75);
552   expected = FilterOperation::CreateOpacityFilter(0.625f);
553   EXPECT_EQ(expected, blended);
554
555   blended = FilterOperation::Blend(&from, &to, 1.8);
556   expected = FilterOperation::CreateOpacityFilter(1.f);
557   EXPECT_EQ(expected, blended);
558 }
559
560 TEST(FilterOperationsTest, BlendOpacityWithNull) {
561   FilterOperation filter = FilterOperation::CreateOpacityFilter(0.f);
562
563   FilterOperation blended = FilterOperation::Blend(&filter, nullptr, 0.25);
564   FilterOperation expected = FilterOperation::CreateOpacityFilter(0.25f);
565   EXPECT_EQ(expected, blended);
566
567   blended = FilterOperation::Blend(nullptr, &filter, 0.25);
568   expected = FilterOperation::CreateOpacityFilter(0.75f);
569   EXPECT_EQ(expected, blended);
570 }
571
572 TEST(FilterOperationsTest, BlendBlurFilters) {
573   FilterOperation from = FilterOperation::CreateBlurFilter(3.f);
574   FilterOperation to = FilterOperation::CreateBlurFilter(7.f);
575
576   FilterOperation blended = FilterOperation::Blend(&from, &to, -0.9);
577   FilterOperation expected = FilterOperation::CreateBlurFilter(0.f);
578   EXPECT_EQ(expected, blended);
579
580   blended = FilterOperation::Blend(&from, &to, 0.75);
581   expected = FilterOperation::CreateBlurFilter(6.f);
582   EXPECT_EQ(expected, blended);
583
584   blended = FilterOperation::Blend(&from, &to, 1.5);
585   expected = FilterOperation::CreateBlurFilter(9.f);
586   EXPECT_EQ(expected, blended);
587 }
588
589 TEST(FilterOperationsTest, BlendBlurWithNull) {
590   FilterOperation filter = FilterOperation::CreateBlurFilter(1.f);
591
592   FilterOperation blended = FilterOperation::Blend(&filter, nullptr, 0.25);
593   FilterOperation expected = FilterOperation::CreateBlurFilter(0.75f);
594   EXPECT_EQ(expected, blended);
595
596   blended = FilterOperation::Blend(nullptr, &filter, 0.25);
597   expected = FilterOperation::CreateBlurFilter(0.25f);
598   EXPECT_EQ(expected, blended);
599 }
600
601 TEST(FilterOperationsTest, BlendDropShadowFilters) {
602   FilterOperation from = FilterOperation::CreateDropShadowFilter(
603       gfx::Point(0, 0), 2.f, SkColor4f{0.13f, 0.27f, 0.53f, 0.06f});
604   FilterOperation to = FilterOperation::CreateDropShadowFilter(
605       gfx::Point(3, 5), 6.f, SkColor4f{0.12f, 0.24f, 0.47f, 0.2f});
606
607   // In the test below we have to use EXPECT_NEAR as the color contain float for
608   // the components. In order to properly test the filterOperation we are
609   // equalizing the color aftewards.
610   FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
611   FilterOperation expected = FilterOperation::CreateDropShadowFilter(
612       gfx::Point(-2, -4), 0.f, SkColor4f{0.0f, 0.0f, 0.0f, 0.0f});
613   SkColor4f blended_color = blended.drop_shadow_color();
614   SkColor4f expected_color = expected.drop_shadow_color();
615   EXPECT_NEAR(blended_color.fR, expected_color.fR, 0.0001f);
616   EXPECT_NEAR(blended_color.fG, expected_color.fG, 0.0001f);
617   EXPECT_NEAR(blended_color.fB, expected_color.fB, 0.0001f);
618   EXPECT_NEAR(blended_color.fA, expected_color.fA, 0.0001f);
619   expected.set_drop_shadow_color(blended_color);
620   EXPECT_EQ(expected, blended);
621
622   blended = FilterOperation::Blend(&from, &to, 0.25);
623   expected = FilterOperation::CreateDropShadowFilter(
624       gfx::Point(1, 1), 3.f, SkColor4f{0.1247f, 0.2542f, 0.4984f, 0.095f});
625   blended_color = blended.drop_shadow_color();
626   expected_color = expected.drop_shadow_color();
627   EXPECT_NEAR(blended_color.fR, expected_color.fR, 0.0001f);
628   EXPECT_NEAR(blended_color.fG, expected_color.fG, 0.0001f);
629   EXPECT_NEAR(blended_color.fB, expected_color.fB, 0.0001f);
630   EXPECT_NEAR(blended_color.fA, expected_color.fA, 0.0001f);
631   expected.set_drop_shadow_color(blended_color);
632   EXPECT_EQ(expected, blended);
633
634   blended = FilterOperation::Blend(&from, &to, 0.75);
635   expected = FilterOperation::CreateDropShadowFilter(
636       gfx::Point(2, 4), 5.f, SkColor4f{0.1209f, 0.2427f, 0.4755f, 0.1649f});
637   blended_color = blended.drop_shadow_color();
638   expected_color = expected.drop_shadow_color();
639   EXPECT_NEAR(blended_color.fR, expected_color.fR, 0.0001f);
640   EXPECT_NEAR(blended_color.fG, expected_color.fG, 0.0001f);
641   EXPECT_NEAR(blended_color.fB, expected_color.fB, 0.0001f);
642   EXPECT_NEAR(blended_color.fA, expected_color.fA, 0.0001f);
643   expected.set_drop_shadow_color(blended_color);
644   EXPECT_EQ(expected, blended);
645
646   blended = FilterOperation::Blend(&from, &to, 1.5);
647   expected = FilterOperation::CreateDropShadowFilter(
648       gfx::Point(5, 8), 8.f, SkColor4f{0.1188f, 0.2366f, 0.4633f, 0.27});
649   blended_color = blended.drop_shadow_color();
650   expected_color = expected.drop_shadow_color();
651   EXPECT_NEAR(blended_color.fR, expected_color.fR, 0.0001f);
652   EXPECT_NEAR(blended_color.fG, expected_color.fG, 0.0001f);
653   EXPECT_NEAR(blended_color.fB, expected_color.fB, 0.0001f);
654   EXPECT_NEAR(blended_color.fA, expected_color.fA, 0.0001f);
655   expected.set_drop_shadow_color(blended_color);
656   EXPECT_EQ(expected, blended);
657 }
658
659 TEST(FilterOperationsTest, BlendDropShadowWithNull) {
660   FilterOperation filter = FilterOperation::CreateDropShadowFilter(
661       gfx::Point(4, 4), 4.f, SkColor4f{0.16f, 0.0f, 0.0f, 1.0f});
662
663   FilterOperation blended = FilterOperation::Blend(&filter, nullptr, 0.25);
664   FilterOperation expected = FilterOperation::CreateDropShadowFilter(
665       gfx::Point(3, 3), 3.f, SkColor4f{0.16f, 0.0f, 0.0f, 0.75f});
666   EXPECT_EQ(expected, blended);
667
668   blended = FilterOperation::Blend(nullptr, &filter, 0.25);
669   expected = FilterOperation::CreateDropShadowFilter(
670       gfx::Point(1, 1), 1.f, SkColor4f{0.16f, 0.0f, 0.0f, 0.25f});
671   EXPECT_EQ(expected, blended);
672 }
673
674 TEST(FilterOperationsTest, BlendZoomFilters) {
675   FilterOperation from = FilterOperation::CreateZoomFilter(2.f, 3);
676   FilterOperation to = FilterOperation::CreateZoomFilter(6.f, 0);
677
678   FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
679   FilterOperation expected = FilterOperation::CreateZoomFilter(1.f, 5);
680   EXPECT_EQ(expected, blended);
681
682   blended = FilterOperation::Blend(&from, &to, 0.75);
683   expected = FilterOperation::CreateZoomFilter(5.f, 1);
684   EXPECT_EQ(expected, blended);
685
686   blended = FilterOperation::Blend(&from, &to, 1.5);
687   expected = FilterOperation::CreateZoomFilter(8.f, 0);
688   EXPECT_EQ(expected, blended);
689 }
690
691 TEST(FilterOperationsTest, BlendZoomWithNull) {
692   FilterOperation filter = FilterOperation::CreateZoomFilter(2.f, 1);
693
694   FilterOperation blended = FilterOperation::Blend(&filter, nullptr, 0.25);
695   FilterOperation expected = FilterOperation::CreateZoomFilter(1.75f, 1);
696   EXPECT_EQ(expected, blended);
697
698   blended = FilterOperation::Blend(nullptr, &filter, 0.25);
699   expected = FilterOperation::CreateZoomFilter(1.25f, 0);
700   EXPECT_EQ(expected, blended);
701 }
702
703 TEST(FilterOperationsTest, BlendSaturatingBrightnessFilters) {
704   FilterOperation from = FilterOperation::CreateSaturatingBrightnessFilter(3.f);
705   FilterOperation to = FilterOperation::CreateSaturatingBrightnessFilter(7.f);
706
707   FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
708   FilterOperation expected =
709       FilterOperation::CreateSaturatingBrightnessFilter(0.f);
710   EXPECT_EQ(expected, blended);
711
712   blended = FilterOperation::Blend(&from, &to, 0.75);
713   expected = FilterOperation::CreateSaturatingBrightnessFilter(6.f);
714   EXPECT_EQ(expected, blended);
715
716   blended = FilterOperation::Blend(&from, &to, 1.5);
717   expected = FilterOperation::CreateSaturatingBrightnessFilter(9.f);
718   EXPECT_EQ(expected, blended);
719 }
720
721 TEST(FilterOperationsTest, BlendSaturatingBrightnessWithNull) {
722   FilterOperation filter =
723       FilterOperation::CreateSaturatingBrightnessFilter(1.f);
724
725   FilterOperation blended = FilterOperation::Blend(&filter, nullptr, 0.25);
726   FilterOperation expected =
727       FilterOperation::CreateSaturatingBrightnessFilter(0.75f);
728   EXPECT_EQ(expected, blended);
729
730   blended = FilterOperation::Blend(nullptr, &filter, 0.25);
731   expected = FilterOperation::CreateSaturatingBrightnessFilter(0.25f);
732   EXPECT_EQ(expected, blended);
733 }
734
735 TEST(FilterOperationsTest, BlendReferenceFilters) {
736   sk_sp<PaintFilter> from_filter(
737       sk_make_sp<BlurPaintFilter>(1.f, 1.f, SkTileMode::kDecal, nullptr));
738   sk_sp<PaintFilter> to_filter(
739       sk_make_sp<BlurPaintFilter>(2.f, 2.f, SkTileMode::kDecal, nullptr));
740   FilterOperation from =
741       FilterOperation::CreateReferenceFilter(std::move(from_filter));
742   FilterOperation to =
743       FilterOperation::CreateReferenceFilter(std::move(to_filter));
744
745   FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
746   EXPECT_EQ(from, blended);
747
748   blended = FilterOperation::Blend(&from, &to, 0.5);
749   EXPECT_EQ(from, blended);
750
751   blended = FilterOperation::Blend(&from, &to, 0.6);
752   EXPECT_EQ(to, blended);
753
754   blended = FilterOperation::Blend(&from, &to, 1.5);
755   EXPECT_EQ(to, blended);
756 }
757
758 TEST(FilterOperationsTest, BlendReferenceWithNull) {
759   sk_sp<PaintFilter> image_filter(
760       sk_make_sp<BlurPaintFilter>(1.f, 1.f, SkTileMode::kDecal, nullptr));
761   FilterOperation filter =
762       FilterOperation::CreateReferenceFilter(std::move(image_filter));
763   FilterOperation null_filter = FilterOperation::CreateReferenceFilter(nullptr);
764
765   FilterOperation blended = FilterOperation::Blend(&filter, nullptr, 0.25);
766   EXPECT_EQ(filter, blended);
767   blended = FilterOperation::Blend(&filter, nullptr, 0.75);
768   EXPECT_EQ(null_filter, blended);
769
770   blended = FilterOperation::Blend(nullptr, &filter, 0.25);
771   EXPECT_EQ(null_filter, blended);
772   blended = FilterOperation::Blend(nullptr, &filter, 0.75);
773   EXPECT_EQ(filter, blended);
774 }
775
776 // Tests blending non-empty sequences that have the same length and matching
777 // operations.
778 TEST(FilterOperationsTest, BlendMatchingSequences) {
779   FilterOperations from;
780   FilterOperations to;
781
782   from.Append(FilterOperation::CreateBlurFilter(0.f));
783   to.Append(FilterOperation::CreateBlurFilter(2.f));
784
785   from.Append(FilterOperation::CreateSaturateFilter(4.f));
786   to.Append(FilterOperation::CreateSaturateFilter(0.f));
787
788   from.Append(FilterOperation::CreateZoomFilter(2.0f, 1));
789   to.Append(FilterOperation::CreateZoomFilter(10.f, 9));
790
791   FilterOperations blended = to.Blend(from, -0.75);
792   FilterOperations expected;
793   expected.Append(FilterOperation::CreateBlurFilter(0.f));
794   expected.Append(FilterOperation::CreateSaturateFilter(7.f));
795   expected.Append(FilterOperation::CreateZoomFilter(1.f, 0));
796   EXPECT_EQ(blended, expected);
797
798   blended = to.Blend(from, 0.75);
799   expected.Clear();
800   expected.Append(FilterOperation::CreateBlurFilter(1.5f));
801   expected.Append(FilterOperation::CreateSaturateFilter(1.f));
802   expected.Append(FilterOperation::CreateZoomFilter(8.f, 7));
803   EXPECT_EQ(blended, expected);
804
805   blended = to.Blend(from, 1.5);
806   expected.Clear();
807   expected.Append(FilterOperation::CreateBlurFilter(3.f));
808   expected.Append(FilterOperation::CreateSaturateFilter(0.f));
809   expected.Append(FilterOperation::CreateZoomFilter(14.f, 13));
810   EXPECT_EQ(blended, expected);
811 }
812
813 TEST(FilterOperationsTest, BlendEmptyAndNonEmptySequences) {
814   FilterOperations empty;
815   FilterOperations filters;
816
817   filters.Append(FilterOperation::CreateGrayscaleFilter(0.75f));
818   filters.Append(FilterOperation::CreateBrightnessFilter(2.f));
819   filters.Append(FilterOperation::CreateHueRotateFilter(10.0f));
820
821   FilterOperations blended = empty.Blend(filters, -0.75);
822   FilterOperations expected;
823   expected.Append(FilterOperation::CreateGrayscaleFilter(1.f));
824   expected.Append(FilterOperation::CreateBrightnessFilter(2.75f));
825   expected.Append(FilterOperation::CreateHueRotateFilter(17.5f));
826   EXPECT_EQ(blended, expected);
827
828   blended = empty.Blend(filters, 0.75);
829   expected.Clear();
830   expected.Append(FilterOperation::CreateGrayscaleFilter(0.1875f));
831   expected.Append(FilterOperation::CreateBrightnessFilter(1.25f));
832   expected.Append(FilterOperation::CreateHueRotateFilter(2.5f));
833   EXPECT_EQ(blended, expected);
834
835   blended = empty.Blend(filters, 1.5);
836   expected.Clear();
837   expected.Append(FilterOperation::CreateGrayscaleFilter(0.f));
838   expected.Append(FilterOperation::CreateBrightnessFilter(0.5f));
839   expected.Append(FilterOperation::CreateHueRotateFilter(-5.f));
840   EXPECT_EQ(blended, expected);
841
842   blended = filters.Blend(empty, -0.75);
843   expected.Clear();
844   expected.Append(FilterOperation::CreateGrayscaleFilter(0.f));
845   expected.Append(FilterOperation::CreateBrightnessFilter(0.25f));
846   expected.Append(FilterOperation::CreateHueRotateFilter(-7.5f));
847   EXPECT_EQ(blended, expected);
848
849   blended = filters.Blend(empty, 0.75);
850   expected.Clear();
851   expected.Append(FilterOperation::CreateGrayscaleFilter(0.5625f));
852   expected.Append(FilterOperation::CreateBrightnessFilter(1.75f));
853   expected.Append(FilterOperation::CreateHueRotateFilter(7.5f));
854   EXPECT_EQ(blended, expected);
855
856   blended = filters.Blend(empty, 1.5);
857   expected.Clear();
858   expected.Append(FilterOperation::CreateGrayscaleFilter(1.f));
859   expected.Append(FilterOperation::CreateBrightnessFilter(2.5f));
860   expected.Append(FilterOperation::CreateHueRotateFilter(15.f));
861   EXPECT_EQ(blended, expected);
862 }
863
864 TEST(FilterOperationsTest, BlendEmptySequences) {
865   FilterOperations empty;
866
867   FilterOperations blended = empty.Blend(empty, -0.75);
868   EXPECT_EQ(blended, empty);
869
870   blended = empty.Blend(empty, 0.75);
871   EXPECT_EQ(blended, empty);
872
873   blended = empty.Blend(empty, 1.5);
874   EXPECT_EQ(blended, empty);
875 }
876
877 // Tests blending non-empty sequences that have non-matching operations.
878 TEST(FilterOperationsTest, BlendNonMatchingSequences) {
879   FilterOperations from;
880   FilterOperations to;
881
882   from.Append(FilterOperation::CreateSaturateFilter(3.f));
883   from.Append(FilterOperation::CreateBlurFilter(2.f));
884   to.Append(FilterOperation::CreateSaturateFilter(4.f));
885   to.Append(FilterOperation::CreateHueRotateFilter(0.5f));
886
887   FilterOperations blended = to.Blend(from, -0.75);
888   EXPECT_EQ(to, blended);
889   blended = to.Blend(from, 0.75);
890   EXPECT_EQ(to, blended);
891   blended = to.Blend(from, 1.5);
892   EXPECT_EQ(to, blended);
893 }
894
895 // Tests blending non-empty sequences of different sizes.
896 TEST(FilterOperationsTest, BlendRaggedSequences) {
897   FilterOperations from;
898   FilterOperations to;
899
900   from.Append(FilterOperation::CreateSaturateFilter(3.f));
901   from.Append(FilterOperation::CreateBlurFilter(2.f));
902   to.Append(FilterOperation::CreateSaturateFilter(4.f));
903
904   FilterOperations blended = to.Blend(from, -0.75);
905   FilterOperations expected;
906   expected.Append(FilterOperation::CreateSaturateFilter(2.25f));
907   expected.Append(FilterOperation::CreateBlurFilter(3.5f));
908   EXPECT_EQ(expected, blended);
909
910   blended = to.Blend(from, 0.75);
911   expected.Clear();
912   expected.Append(FilterOperation::CreateSaturateFilter(3.75f));
913   expected.Append(FilterOperation::CreateBlurFilter(0.5f));
914   EXPECT_EQ(expected, blended);
915
916   blended = to.Blend(from, 1.5);
917   expected.Clear();
918   expected.Append(FilterOperation::CreateSaturateFilter(4.5f));
919   expected.Append(FilterOperation::CreateBlurFilter(0.f));
920   EXPECT_EQ(expected, blended);
921
922   from.Append(FilterOperation::CreateOpacityFilter(1.f));
923   to.Append(FilterOperation::CreateOpacityFilter(1.f));
924   blended = to.Blend(from, -0.75);
925   EXPECT_EQ(to, blended);
926   blended = to.Blend(from, 0.75);
927   EXPECT_EQ(to, blended);
928   blended = to.Blend(from, 1.5);
929   EXPECT_EQ(to, blended);
930 }
931
932 TEST(FilterOperationsTest, ToString) {
933   FilterOperations filters;
934   EXPECT_EQ(std::string("{\"FilterOperations\":[]}"), filters.ToString());
935
936   filters.Append(FilterOperation::CreateSaturateFilter(3.f));
937   filters.Append(FilterOperation::CreateBlurFilter(2.f));
938   EXPECT_EQ(std::string("{\"FilterOperations\":[{\"type\":2,\"amount\":3.0},"
939                         "{\"type\":8,\"amount\":2.0}]}"),
940             filters.ToString());
941 }
942
943 TEST(FilterOperationsTest, HasFilterOfType) {
944   FilterOperations filters;
945
946   EXPECT_FALSE(filters.HasFilterOfType(FilterOperation::GRAYSCALE));
947   EXPECT_FALSE(filters.HasFilterOfType(FilterOperation::BLUR));
948   EXPECT_FALSE(filters.HasReferenceFilter());
949   EXPECT_FALSE(filters.HasFilterOfType(FilterOperation::OPACITY));
950   EXPECT_FALSE(filters.HasFilterOfType(FilterOperation::ZOOM));
951
952   filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
953   filters.Append(FilterOperation::CreateBlurFilter(20));
954   sk_sp<PaintFilter> filter(
955       sk_make_sp<BlurPaintFilter>(1.f, 1.f, SkTileMode::kDecal, nullptr));
956   filters.Append(FilterOperation::CreateReferenceFilter(std::move(filter)));
957
958   EXPECT_TRUE(filters.HasFilterOfType(FilterOperation::GRAYSCALE));
959   EXPECT_TRUE(filters.HasFilterOfType(FilterOperation::BLUR));
960   EXPECT_TRUE(filters.HasReferenceFilter());
961   EXPECT_FALSE(filters.HasFilterOfType(FilterOperation::OPACITY));
962   EXPECT_FALSE(filters.HasFilterOfType(FilterOperation::ZOOM));
963 }
964
965 TEST(FilterOperationsTest, MaximumPixelMovement) {
966   FilterOperations filters;
967
968   filters.Append(FilterOperation::CreateBlurFilter(20));
969   EXPECT_FLOAT_EQ(20.f * 3, filters.MaximumPixelMovement());
970
971   filters.Clear();
972   filters.Append(FilterOperation::CreateDropShadowFilter(
973       gfx::Point(3, -8), 20, SkColors::kTransparent));
974   float max_movement = fmax(std::abs(3), std::abs(-8)) + 20.f * 3;
975   EXPECT_FLOAT_EQ(max_movement, filters.MaximumPixelMovement());
976
977   filters.Clear();
978   filters.Append(FilterOperation::CreateZoomFilter(2, 3));
979   // max movement = zoom_inset = 3
980   EXPECT_FLOAT_EQ(3.f, filters.MaximumPixelMovement());
981
982   filters.Clear();
983   filters.Append(FilterOperation::CreateReferenceFilter(
984       sk_make_sp<OffsetPaintFilter>(10, 10, nullptr)));
985   // max movement = 100.
986   EXPECT_FLOAT_EQ(100.f, filters.MaximumPixelMovement());
987
988   // For filters that don't move pixels. HasFilterThatMovesPixels() = false.
989   filters.Clear();
990   filters.Append(FilterOperation::CreateOpacityFilter(0.25f));
991   FilterOperation::Matrix matrix = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10,
992                                     11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
993   filters.Append(FilterOperation::CreateColorMatrixFilter(matrix));
994   filters.Append(FilterOperation::CreateGrayscaleFilter(0.75f));
995   filters.Append(FilterOperation::CreateSepiaFilter(0.625f));
996   filters.Append(FilterOperation::CreateSaturateFilter(1.25f));
997   filters.Append(FilterOperation::CreateHueRotateFilter(6.f));
998   filters.Append(FilterOperation::CreateInvertFilter(0.75f));
999   filters.Append(FilterOperation::CreateBrightnessFilter(9.f));
1000   filters.Append(FilterOperation::CreateContrastFilter(3.f));
1001   filters.Append(FilterOperation::CreateSaturatingBrightnessFilter(7.f));
1002
1003   EXPECT_FLOAT_EQ(0.f, filters.MaximumPixelMovement());
1004 }
1005
1006 }  // namespace
1007 }  // namespace cc