IndexedDB: fsync after transactions.
[chromium-blink-merge.git] / cc / output / filter_operation.cc
blob181fa8a395afbdf6710031083efae2e387a0c147
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.
5 #include <algorithm>
7 #include "base/values.h"
8 #include "cc/base/math_util.h"
9 #include "cc/output/filter_operation.h"
10 #include "third_party/skia/include/core/SkMath.h"
11 #include "ui/gfx/animation/tween.h"
13 namespace cc {
15 bool FilterOperation::operator==(const FilterOperation& other) const {
16 if (type_ != other.type_)
17 return false;
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 return amount_ == other.amount_;
30 FilterOperation::FilterOperation(FilterType type, float amount)
31 : type_(type),
32 amount_(amount),
33 drop_shadow_offset_(0, 0),
34 drop_shadow_color_(0),
35 zoom_inset_(0) {
36 DCHECK_NE(type_, DROP_SHADOW);
37 DCHECK_NE(type_, COLOR_MATRIX);
38 DCHECK_NE(type_, REFERENCE);
39 memset(matrix_, 0, sizeof(matrix_));
42 FilterOperation::FilterOperation(FilterType type,
43 gfx::Point offset,
44 float stdDeviation,
45 SkColor color)
46 : type_(type),
47 amount_(stdDeviation),
48 drop_shadow_offset_(offset),
49 drop_shadow_color_(color),
50 zoom_inset_(0) {
51 DCHECK_EQ(type_, DROP_SHADOW);
52 memset(matrix_, 0, sizeof(matrix_));
55 FilterOperation::FilterOperation(FilterType type, SkScalar matrix[20])
56 : type_(type),
57 amount_(0),
58 drop_shadow_offset_(0, 0),
59 drop_shadow_color_(0),
60 zoom_inset_(0) {
61 DCHECK_EQ(type_, COLOR_MATRIX);
62 memcpy(matrix_, matrix, sizeof(matrix_));
65 FilterOperation::FilterOperation(FilterType type, float amount, int inset)
66 : type_(type),
67 amount_(amount),
68 drop_shadow_offset_(0, 0),
69 drop_shadow_color_(0),
70 zoom_inset_(inset) {
71 DCHECK_EQ(type_, ZOOM);
72 memset(matrix_, 0, sizeof(matrix_));
75 FilterOperation::FilterOperation(
76 FilterType type,
77 const skia::RefPtr<SkImageFilter>& image_filter)
78 : type_(type),
79 amount_(0),
80 drop_shadow_offset_(0, 0),
81 drop_shadow_color_(0),
82 image_filter_(image_filter),
83 zoom_inset_(0) {
84 DCHECK_EQ(type_, REFERENCE);
85 memset(matrix_, 0, sizeof(matrix_));
88 FilterOperation::FilterOperation(const FilterOperation& other)
89 : type_(other.type_),
90 amount_(other.amount_),
91 drop_shadow_offset_(other.drop_shadow_offset_),
92 drop_shadow_color_(other.drop_shadow_color_),
93 image_filter_(other.image_filter_),
94 zoom_inset_(other.zoom_inset_) {
95 memcpy(matrix_, other.matrix_, sizeof(matrix_));
98 FilterOperation::~FilterOperation() {
101 static FilterOperation CreateNoOpFilter(FilterOperation::FilterType type) {
102 switch (type) {
103 case FilterOperation::GRAYSCALE:
104 return FilterOperation::CreateGrayscaleFilter(0.f);
105 case FilterOperation::SEPIA:
106 return FilterOperation::CreateSepiaFilter(0.f);
107 case FilterOperation::SATURATE:
108 return FilterOperation::CreateSaturateFilter(1.f);
109 case FilterOperation::HUE_ROTATE:
110 return FilterOperation::CreateHueRotateFilter(0.f);
111 case FilterOperation::INVERT:
112 return FilterOperation::CreateInvertFilter(0.f);
113 case FilterOperation::BRIGHTNESS:
114 return FilterOperation::CreateBrightnessFilter(1.f);
115 case FilterOperation::CONTRAST:
116 return FilterOperation::CreateContrastFilter(1.f);
117 case FilterOperation::OPACITY:
118 return FilterOperation::CreateOpacityFilter(1.f);
119 case FilterOperation::BLUR:
120 return FilterOperation::CreateBlurFilter(0.f);
121 case FilterOperation::DROP_SHADOW:
122 return FilterOperation::CreateDropShadowFilter(
123 gfx::Point(0, 0), 0.f, SK_ColorTRANSPARENT);
124 case FilterOperation::COLOR_MATRIX: {
125 SkScalar matrix[20];
126 memset(matrix, 0, 20 * sizeof(SkScalar));
127 matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1.f;
128 return FilterOperation::CreateColorMatrixFilter(matrix);
130 case FilterOperation::ZOOM:
131 return FilterOperation::CreateZoomFilter(1.f, 0);
132 case FilterOperation::SATURATING_BRIGHTNESS:
133 return FilterOperation::CreateSaturatingBrightnessFilter(0.f);
134 case FilterOperation::REFERENCE:
135 return FilterOperation::CreateReferenceFilter(
136 skia::RefPtr<SkImageFilter>());
138 NOTREACHED();
139 return FilterOperation::CreateEmptyFilter();
142 static float ClampAmountForFilterType(float amount,
143 FilterOperation::FilterType type) {
144 switch (type) {
145 case FilterOperation::GRAYSCALE:
146 case FilterOperation::SEPIA:
147 case FilterOperation::INVERT:
148 case FilterOperation::OPACITY:
149 return MathUtil::ClampToRange(amount, 0.f, 1.f);
150 case FilterOperation::SATURATE:
151 case FilterOperation::BRIGHTNESS:
152 case FilterOperation::CONTRAST:
153 case FilterOperation::BLUR:
154 case FilterOperation::DROP_SHADOW:
155 return std::max(amount, 0.f);
156 case FilterOperation::ZOOM:
157 return std::max(amount, 1.f);
158 case FilterOperation::HUE_ROTATE:
159 case FilterOperation::SATURATING_BRIGHTNESS:
160 return amount;
161 case FilterOperation::COLOR_MATRIX:
162 case FilterOperation::REFERENCE:
163 NOTREACHED();
164 return amount;
166 NOTREACHED();
167 return amount;
170 // static
171 FilterOperation FilterOperation::Blend(const FilterOperation* from,
172 const FilterOperation* to,
173 double progress) {
174 FilterOperation blended_filter = FilterOperation::CreateEmptyFilter();
176 if (!from && !to)
177 return blended_filter;
179 const FilterOperation& from_op = from ? *from : CreateNoOpFilter(to->type());
180 const FilterOperation& to_op = to ? *to : CreateNoOpFilter(from->type());
182 if (from_op.type() != to_op.type())
183 return blended_filter;
185 DCHECK(to_op.type() != FilterOperation::COLOR_MATRIX);
186 blended_filter.set_type(to_op.type());
188 if (to_op.type() == FilterOperation::REFERENCE) {
189 if (progress > 0.5)
190 blended_filter.set_image_filter(to_op.image_filter());
191 else
192 blended_filter.set_image_filter(from_op.image_filter());
193 return blended_filter;
196 blended_filter.set_amount(ClampAmountForFilterType(
197 gfx::Tween::FloatValueBetween(progress, from_op.amount(), to_op.amount()),
198 to_op.type()));
200 if (to_op.type() == FilterOperation::DROP_SHADOW) {
201 gfx::Point blended_offset(
202 gfx::Tween::LinearIntValueBetween(progress,
203 from_op.drop_shadow_offset().x(),
204 to_op.drop_shadow_offset().x()),
205 gfx::Tween::LinearIntValueBetween(progress,
206 from_op.drop_shadow_offset().y(),
207 to_op.drop_shadow_offset().y()));
208 blended_filter.set_drop_shadow_offset(blended_offset);
209 blended_filter.set_drop_shadow_color(gfx::Tween::ColorValueBetween(
210 progress, from_op.drop_shadow_color(), to_op.drop_shadow_color()));
211 } else if (to_op.type() == FilterOperation::ZOOM) {
212 blended_filter.set_zoom_inset(
213 std::max(gfx::Tween::LinearIntValueBetween(
214 from_op.zoom_inset(), to_op.zoom_inset(), progress),
215 0));
218 return blended_filter;
221 scoped_ptr<base::Value> FilterOperation::AsValue() const {
222 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue);
223 value->SetInteger("type", type_);
224 switch (type_) {
225 case FilterOperation::GRAYSCALE:
226 case FilterOperation::SEPIA:
227 case FilterOperation::SATURATE:
228 case FilterOperation::HUE_ROTATE:
229 case FilterOperation::INVERT:
230 case FilterOperation::BRIGHTNESS:
231 case FilterOperation::CONTRAST:
232 case FilterOperation::OPACITY:
233 case FilterOperation::BLUR:
234 case FilterOperation::SATURATING_BRIGHTNESS:
235 value->SetDouble("amount", amount_);
236 break;
237 case FilterOperation::DROP_SHADOW:
238 value->SetDouble("std_deviation", amount_);
239 value->Set("offset", MathUtil::AsValue(drop_shadow_offset_).release());
240 value->SetInteger("color", drop_shadow_color_);
241 break;
242 case FilterOperation::COLOR_MATRIX: {
243 scoped_ptr<base::ListValue> matrix(new base::ListValue);
244 for (size_t i = 0; i < arraysize(matrix_); ++i)
245 matrix->AppendDouble(matrix_[i]);
246 value->Set("matrix", matrix.release());
247 break;
249 case FilterOperation::ZOOM:
250 value->SetDouble("amount", amount_);
251 value->SetDouble("inset", zoom_inset_);
252 break;
253 case FilterOperation::REFERENCE: {
254 int count_inputs = 0;
255 bool can_filter_image_gpu = false;
256 if (image_filter_) {
257 count_inputs = image_filter_->countInputs();
258 can_filter_image_gpu = image_filter_->canFilterImageGPU();
260 value->SetBoolean("is_null", !image_filter_);
261 value->SetInteger("count_inputs", count_inputs);
262 value->SetBoolean("can_filter_image_gpu", can_filter_image_gpu);
263 break;
266 return value.PassAs<base::Value>();
269 } // namespace cc