1// Copyright 2012 The Chromium Authors. All rights reserved.
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 "cc/output/render_surface_filters.h"
6
7#include "cc/output/filter_operation.h"
8#include "cc/output/filter_operations.h"
9#include "testing/gtest/include/gtest/gtest.h"
10
11namespace cc {
12namespace {
13
14// Checks whether op can be combined with a following color matrix.
15bool IsCombined(const FilterOperation& op) {
16  FilterOperations filters;
17  filters.Append(op);
18  // brightness(0.0f) is identity.
19  filters.Append(FilterOperation::CreateBrightnessFilter(0.0f));
20  FilterOperations optimized = RenderSurfaceFilters::Optimize(filters);
21  return optimized.size() == 1;
22}
23
24TEST(RenderSurfaceFiltersTest, TestColorMatrixFiltersCombined) {
25  // Several filters should always combine for any amount between 0 and 1:
26  // grayscale, saturate, invert, contrast, opacity.
27  EXPECT_TRUE(IsCombined(FilterOperation::CreateGrayscaleFilter(0.0f)));
28  // Note that we use 0.3f to avoid "argument is truncated from 'double' to
29  // 'float'" warnings on Windows. 0.5f is exactly representable as a float, so
30  // there is no warning.
31  EXPECT_TRUE(IsCombined(FilterOperation::CreateGrayscaleFilter(0.3f)));
32  EXPECT_TRUE(IsCombined(FilterOperation::CreateGrayscaleFilter(0.5f)));
33  EXPECT_TRUE(IsCombined(FilterOperation::CreateGrayscaleFilter(1.0f)));
34
35  EXPECT_TRUE(IsCombined(FilterOperation::CreateSaturateFilter(0.0f)));
36  EXPECT_TRUE(IsCombined(FilterOperation::CreateSaturateFilter(0.3f)));
37  EXPECT_TRUE(IsCombined(FilterOperation::CreateSaturateFilter(0.5)));
38  EXPECT_TRUE(IsCombined(FilterOperation::CreateSaturateFilter(1.0f)));
39
40  EXPECT_TRUE(IsCombined(FilterOperation::CreateInvertFilter(0.0f)));
41  EXPECT_TRUE(IsCombined(FilterOperation::CreateInvertFilter(0.3f)));
42  EXPECT_TRUE(IsCombined(FilterOperation::CreateInvertFilter(0.5)));
43  EXPECT_TRUE(IsCombined(FilterOperation::CreateInvertFilter(1.0f)));
44
45  EXPECT_TRUE(IsCombined(FilterOperation::CreateContrastFilter(0.0f)));
46  EXPECT_TRUE(IsCombined(FilterOperation::CreateContrastFilter(0.3f)));
47  EXPECT_TRUE(IsCombined(FilterOperation::CreateContrastFilter(0.5)));
48  EXPECT_TRUE(IsCombined(FilterOperation::CreateContrastFilter(1.0f)));
49
50  EXPECT_TRUE(IsCombined(FilterOperation::CreateOpacityFilter(0.0f)));
51  EXPECT_TRUE(IsCombined(FilterOperation::CreateOpacityFilter(0.3f)));
52  EXPECT_TRUE(IsCombined(FilterOperation::CreateOpacityFilter(0.5)));
53  EXPECT_TRUE(IsCombined(FilterOperation::CreateOpacityFilter(1.0f)));
54
55  // Brightness combines when amount <= 1
56  EXPECT_TRUE(IsCombined(FilterOperation::CreateBrightnessFilter(0.5)));
57  EXPECT_TRUE(IsCombined(FilterOperation::CreateBrightnessFilter(1.0f)));
58  EXPECT_FALSE(IsCombined(FilterOperation::CreateBrightnessFilter(1.5)));
59
60  // SaturatingBrightness combines only when amount == 0
61  EXPECT_TRUE(
62      IsCombined(FilterOperation::CreateSaturatingBrightnessFilter(0.0f)));
63  EXPECT_FALSE(
64      IsCombined(FilterOperation::CreateSaturatingBrightnessFilter(0.5)));
65  EXPECT_FALSE(
66      IsCombined(FilterOperation::CreateSaturatingBrightnessFilter(1.0f)));
67
68  // Several filters should never combine: blur, drop-shadow.
69  EXPECT_FALSE(IsCombined(FilterOperation::CreateBlurFilter(3.0f)));
70  EXPECT_FALSE(IsCombined(FilterOperation::CreateDropShadowFilter(
71      gfx::Point(2, 2), 3.0f, 0xffffffff)));
72
73  // sepia and hue may or may not combine depending on the value.
74  EXPECT_TRUE(IsCombined(FilterOperation::CreateSepiaFilter(0.0f)));
75  EXPECT_FALSE(IsCombined(FilterOperation::CreateSepiaFilter(1.0f)));
76  EXPECT_TRUE(IsCombined(FilterOperation::CreateHueRotateFilter(0.0f)));
77  EXPECT_FALSE(IsCombined(FilterOperation::CreateHueRotateFilter(180.0f)));
78
79  float matrix1[20] = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
80                        0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
81                        0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
82                        0.0f, 0.0f, 0.0f, 1.0f, 0.0f, };
83  EXPECT_TRUE(IsCombined(FilterOperation::CreateColorMatrixFilter(matrix1)));
84
85  float matrix2[20] = { 1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
86                        0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
87                        0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
88                        0.0f, 0.0f, 0.0f, 1.0f, 0.0f, };
89  EXPECT_FALSE(
90      IsCombined(FilterOperation::CreateColorMatrixFilter(matrix2)));
91
92  float matrix3[20] = { 0.25f, 0.0f, 0.0f, 0.0f, 255.0f * 0.75f,
93                        0.0f,  1.0f, 0.0f, 0.0f, 0.0f,
94                        0.0f,  0.0f, 1.0f, 0.0f, 0.0f,
95                        0.0f,  0.0f, 0.0f, 1.0f, 0.0f, };
96  EXPECT_TRUE(IsCombined(FilterOperation::CreateColorMatrixFilter(matrix3)));
97
98  float matrix4[20] = { -0.25f, 0.75f, 0.0f, 0.0f, 255.0f * 0.25f,
99                         0.0f,  1.0f,  0.0f, 0.0f, 0.0f,
100                         0.0f,  0.0f,  1.0f, 0.0f, 0.0f,
101                         0.0f,  0.0f,  0.0f, 1.0f, 0.0f, };
102  EXPECT_TRUE(IsCombined(FilterOperation::CreateColorMatrixFilter(matrix4)));
103}
104
105TEST(RenderSurfaceFiltersTest, TestOptimize) {
106  FilterOperation combines(FilterOperation::CreateBrightnessFilter(1.0f));
107  FilterOperation doesnt_combine(
108      FilterOperation::CreateBrightnessFilter(1.5f));
109
110  FilterOperations filters;
111  FilterOperations optimized = RenderSurfaceFilters::Optimize(filters);
112  EXPECT_EQ(0u, optimized.size());
113
114  filters.Append(combines);
115  optimized = RenderSurfaceFilters::Optimize(filters);
116  EXPECT_EQ(1u, optimized.size());
117
118  filters.Append(combines);
119  optimized = RenderSurfaceFilters::Optimize(filters);
120  EXPECT_EQ(1u, optimized.size());
121
122  filters.Append(doesnt_combine);
123  optimized = RenderSurfaceFilters::Optimize(filters);
124  EXPECT_EQ(1u, optimized.size());
125
126  filters.Append(combines);
127  optimized = RenderSurfaceFilters::Optimize(filters);
128  EXPECT_EQ(2u, optimized.size());
129
130  filters.Append(doesnt_combine);
131  optimized = RenderSurfaceFilters::Optimize(filters);
132  EXPECT_EQ(2u, optimized.size());
133
134  filters.Append(doesnt_combine);
135  optimized = RenderSurfaceFilters::Optimize(filters);
136  EXPECT_EQ(3u, optimized.size());
137}
138
139}  // namespace
140}  // namespace cc
141