1 // Copyright 2013 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.
7 #include "base/trace_event/trace_event_argument.h"
8 #include "base/values.h"
9 #include "cc/base/math_util.h"
10 #include "cc/output/filter_operation.h"
11 #include "ui/gfx/animation/tween.h"
15 bool FilterOperation::operator==(const FilterOperation
& other
) const {
16 if (type_
!= other
.type_
)
18 if (type_
== COLOR_MATRIX
)
19 return !memcmp(matrix_
, other
.matrix_
, sizeof(matrix_
));
20 if (type_
== DROP_SHADOW
) {
21 return amount_
== other
.amount_
&&
22 drop_shadow_offset_
== other
.drop_shadow_offset_
&&
23 drop_shadow_color_
== other
.drop_shadow_color_
;
25 if (type_
== REFERENCE
)
26 return image_filter_
.get() == other
.image_filter_
.get();
27 if (type_
== ALPHA_THRESHOLD
) {
28 return region_
== other
.region_
&&
29 amount_
== other
.amount_
&&
30 outer_threshold_
== other
.outer_threshold_
;
32 return amount_
== other
.amount_
;
35 FilterOperation::FilterOperation(FilterType type
, float amount
)
39 drop_shadow_offset_(0, 0),
40 drop_shadow_color_(0),
42 DCHECK_NE(type_
, DROP_SHADOW
);
43 DCHECK_NE(type_
, COLOR_MATRIX
);
44 DCHECK_NE(type_
, REFERENCE
);
45 memset(matrix_
, 0, sizeof(matrix_
));
48 FilterOperation::FilterOperation(FilterType type
,
49 const gfx::Point
& offset
,
53 amount_(stdDeviation
),
55 drop_shadow_offset_(offset
),
56 drop_shadow_color_(color
),
58 DCHECK_EQ(type_
, DROP_SHADOW
);
59 memset(matrix_
, 0, sizeof(matrix_
));
62 FilterOperation::FilterOperation(FilterType type
, SkScalar matrix
[20])
66 drop_shadow_offset_(0, 0),
67 drop_shadow_color_(0),
69 DCHECK_EQ(type_
, COLOR_MATRIX
);
70 memcpy(matrix_
, matrix
, sizeof(matrix_
));
73 FilterOperation::FilterOperation(FilterType type
, float amount
, int inset
)
77 drop_shadow_offset_(0, 0),
78 drop_shadow_color_(0),
80 DCHECK_EQ(type_
, ZOOM
);
81 memset(matrix_
, 0, sizeof(matrix_
));
84 FilterOperation::FilterOperation(
86 const skia::RefPtr
<SkImageFilter
>& image_filter
)
90 drop_shadow_offset_(0, 0),
91 drop_shadow_color_(0),
92 image_filter_(image_filter
),
94 DCHECK_EQ(type_
, REFERENCE
);
95 memset(matrix_
, 0, sizeof(matrix_
));
98 FilterOperation::FilterOperation(FilterType type
,
99 const SkRegion
& region
,
100 float inner_threshold
,
101 float outer_threshold
)
103 amount_(inner_threshold
),
104 outer_threshold_(outer_threshold
),
105 drop_shadow_offset_(0, 0),
106 drop_shadow_color_(0),
109 DCHECK_EQ(type_
, ALPHA_THRESHOLD
);
110 memset(matrix_
, 0, sizeof(matrix_
));
113 FilterOperation::FilterOperation(const FilterOperation
& other
)
114 : type_(other
.type_
),
115 amount_(other
.amount_
),
116 outer_threshold_(other
.outer_threshold_
),
117 drop_shadow_offset_(other
.drop_shadow_offset_
),
118 drop_shadow_color_(other
.drop_shadow_color_
),
119 image_filter_(other
.image_filter_
),
120 zoom_inset_(other
.zoom_inset_
),
121 region_(other
.region_
) {
122 memcpy(matrix_
, other
.matrix_
, sizeof(matrix_
));
125 FilterOperation::~FilterOperation() {
128 static FilterOperation
CreateNoOpFilter(FilterOperation::FilterType type
) {
130 case FilterOperation::GRAYSCALE
:
131 return FilterOperation::CreateGrayscaleFilter(0.f
);
132 case FilterOperation::SEPIA
:
133 return FilterOperation::CreateSepiaFilter(0.f
);
134 case FilterOperation::SATURATE
:
135 return FilterOperation::CreateSaturateFilter(1.f
);
136 case FilterOperation::HUE_ROTATE
:
137 return FilterOperation::CreateHueRotateFilter(0.f
);
138 case FilterOperation::INVERT
:
139 return FilterOperation::CreateInvertFilter(0.f
);
140 case FilterOperation::BRIGHTNESS
:
141 return FilterOperation::CreateBrightnessFilter(1.f
);
142 case FilterOperation::CONTRAST
:
143 return FilterOperation::CreateContrastFilter(1.f
);
144 case FilterOperation::OPACITY
:
145 return FilterOperation::CreateOpacityFilter(1.f
);
146 case FilterOperation::BLUR
:
147 return FilterOperation::CreateBlurFilter(0.f
);
148 case FilterOperation::DROP_SHADOW
:
149 return FilterOperation::CreateDropShadowFilter(
150 gfx::Point(0, 0), 0.f
, SK_ColorTRANSPARENT
);
151 case FilterOperation::COLOR_MATRIX
: {
153 memset(matrix
, 0, 20 * sizeof(SkScalar
));
154 matrix
[0] = matrix
[6] = matrix
[12] = matrix
[18] = 1.f
;
155 return FilterOperation::CreateColorMatrixFilter(matrix
);
157 case FilterOperation::ZOOM
:
158 return FilterOperation::CreateZoomFilter(1.f
, 0);
159 case FilterOperation::SATURATING_BRIGHTNESS
:
160 return FilterOperation::CreateSaturatingBrightnessFilter(0.f
);
161 case FilterOperation::REFERENCE
:
162 return FilterOperation::CreateReferenceFilter(
163 skia::RefPtr
<SkImageFilter
>());
164 case FilterOperation::ALPHA_THRESHOLD
:
165 return FilterOperation::CreateAlphaThresholdFilter(SkRegion(), 1.f
, 0.f
);
168 return FilterOperation::CreateEmptyFilter();
171 static float ClampAmountForFilterType(float amount
,
172 FilterOperation::FilterType type
) {
174 case FilterOperation::GRAYSCALE
:
175 case FilterOperation::SEPIA
:
176 case FilterOperation::INVERT
:
177 case FilterOperation::OPACITY
:
178 case FilterOperation::ALPHA_THRESHOLD
:
179 return MathUtil::ClampToRange(amount
, 0.f
, 1.f
);
180 case FilterOperation::SATURATE
:
181 case FilterOperation::BRIGHTNESS
:
182 case FilterOperation::CONTRAST
:
183 case FilterOperation::BLUR
:
184 case FilterOperation::DROP_SHADOW
:
185 return std::max(amount
, 0.f
);
186 case FilterOperation::ZOOM
:
187 return std::max(amount
, 1.f
);
188 case FilterOperation::HUE_ROTATE
:
189 case FilterOperation::SATURATING_BRIGHTNESS
:
191 case FilterOperation::COLOR_MATRIX
:
192 case FilterOperation::REFERENCE
:
201 FilterOperation
FilterOperation::Blend(const FilterOperation
* from
,
202 const FilterOperation
* to
,
204 FilterOperation blended_filter
= FilterOperation::CreateEmptyFilter();
207 return blended_filter
;
209 const FilterOperation
& from_op
= from
? *from
: CreateNoOpFilter(to
->type());
210 const FilterOperation
& to_op
= to
? *to
: CreateNoOpFilter(from
->type());
212 if (from_op
.type() != to_op
.type())
213 return blended_filter
;
215 DCHECK(to_op
.type() != FilterOperation::COLOR_MATRIX
);
216 blended_filter
.set_type(to_op
.type());
218 if (to_op
.type() == FilterOperation::REFERENCE
) {
220 blended_filter
.set_image_filter(to_op
.image_filter());
222 blended_filter
.set_image_filter(from_op
.image_filter());
223 return blended_filter
;
226 blended_filter
.set_amount(ClampAmountForFilterType(
227 gfx::Tween::FloatValueBetween(progress
, from_op
.amount(), to_op
.amount()),
230 if (to_op
.type() == FilterOperation::DROP_SHADOW
) {
231 gfx::Point
blended_offset(
232 gfx::Tween::LinearIntValueBetween(progress
,
233 from_op
.drop_shadow_offset().x(),
234 to_op
.drop_shadow_offset().x()),
235 gfx::Tween::LinearIntValueBetween(progress
,
236 from_op
.drop_shadow_offset().y(),
237 to_op
.drop_shadow_offset().y()));
238 blended_filter
.set_drop_shadow_offset(blended_offset
);
239 blended_filter
.set_drop_shadow_color(gfx::Tween::ColorValueBetween(
240 progress
, from_op
.drop_shadow_color(), to_op
.drop_shadow_color()));
241 } else if (to_op
.type() == FilterOperation::ZOOM
) {
242 blended_filter
.set_zoom_inset(
243 std::max(gfx::Tween::LinearIntValueBetween(
244 from_op
.zoom_inset(), to_op
.zoom_inset(), progress
),
246 } else if (to_op
.type() == FilterOperation::ALPHA_THRESHOLD
) {
247 blended_filter
.set_outer_threshold(ClampAmountForFilterType(
248 gfx::Tween::FloatValueBetween(progress
,
249 from_op
.outer_threshold(),
250 to_op
.outer_threshold()),
252 blended_filter
.set_region(to_op
.region());
255 return blended_filter
;
258 void FilterOperation::AsValueInto(base::debug::TracedValue
* value
) const {
259 value
->SetInteger("type", type_
);
261 case FilterOperation::GRAYSCALE
:
262 case FilterOperation::SEPIA
:
263 case FilterOperation::SATURATE
:
264 case FilterOperation::HUE_ROTATE
:
265 case FilterOperation::INVERT
:
266 case FilterOperation::BRIGHTNESS
:
267 case FilterOperation::CONTRAST
:
268 case FilterOperation::OPACITY
:
269 case FilterOperation::BLUR
:
270 case FilterOperation::SATURATING_BRIGHTNESS
:
271 value
->SetDouble("amount", amount_
);
273 case FilterOperation::DROP_SHADOW
:
274 value
->SetDouble("std_deviation", amount_
);
275 MathUtil::AddToTracedValue("offset", drop_shadow_offset_
, value
);
276 value
->SetInteger("color", drop_shadow_color_
);
278 case FilterOperation::COLOR_MATRIX
: {
279 value
->BeginArray("matrix");
280 for (size_t i
= 0; i
< arraysize(matrix_
); ++i
)
281 value
->AppendDouble(matrix_
[i
]);
285 case FilterOperation::ZOOM
:
286 value
->SetDouble("amount", amount_
);
287 value
->SetDouble("inset", zoom_inset_
);
289 case FilterOperation::REFERENCE
: {
290 int count_inputs
= 0;
291 bool can_filter_image_gpu
= false;
293 count_inputs
= image_filter_
->countInputs();
294 can_filter_image_gpu
= image_filter_
->canFilterImageGPU();
296 value
->SetBoolean("is_null", !image_filter_
);
297 value
->SetInteger("count_inputs", count_inputs
);
298 value
->SetBoolean("can_filter_image_gpu", can_filter_image_gpu
);
301 case FilterOperation::ALPHA_THRESHOLD
: {
302 value
->SetDouble("inner_threshold", amount_
);
303 value
->SetDouble("outer_threshold", outer_threshold_
);
304 scoped_ptr
<base::ListValue
> region_value(new base::ListValue());
305 value
->BeginArray("region");
306 for (SkRegion::Iterator
it(region_
); !it
.done(); it
.next()) {
307 value
->AppendInteger(it
.rect().x());
308 value
->AppendInteger(it
.rect().y());
309 value
->AppendInteger(it
.rect().width());
310 value
->AppendInteger(it
.rect().height());