| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include <algorithm> | |
| 6 | |
| 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" | |
| 12 | |
| 13 namespace cc { | |
| 14 | |
| 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_; | |
| 24 } | |
| 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_; | |
| 31 } | |
| 32 return amount_ == other.amount_; | |
| 33 } | |
| 34 | |
| 35 FilterOperation::FilterOperation(FilterType type, float amount) | |
| 36 : type_(type), | |
| 37 amount_(amount), | |
| 38 outer_threshold_(0), | |
| 39 drop_shadow_offset_(0, 0), | |
| 40 drop_shadow_color_(0), | |
| 41 zoom_inset_(0) { | |
| 42 DCHECK_NE(type_, DROP_SHADOW); | |
| 43 DCHECK_NE(type_, COLOR_MATRIX); | |
| 44 DCHECK_NE(type_, REFERENCE); | |
| 45 memset(matrix_, 0, sizeof(matrix_)); | |
| 46 } | |
| 47 | |
| 48 FilterOperation::FilterOperation(FilterType type, | |
| 49 const gfx::Point& offset, | |
| 50 float stdDeviation, | |
| 51 SkColor color) | |
| 52 : type_(type), | |
| 53 amount_(stdDeviation), | |
| 54 outer_threshold_(0), | |
| 55 drop_shadow_offset_(offset), | |
| 56 drop_shadow_color_(color), | |
| 57 zoom_inset_(0) { | |
| 58 DCHECK_EQ(type_, DROP_SHADOW); | |
| 59 memset(matrix_, 0, sizeof(matrix_)); | |
| 60 } | |
| 61 | |
| 62 FilterOperation::FilterOperation(FilterType type, SkScalar matrix[20]) | |
| 63 : type_(type), | |
| 64 amount_(0), | |
| 65 outer_threshold_(0), | |
| 66 drop_shadow_offset_(0, 0), | |
| 67 drop_shadow_color_(0), | |
| 68 zoom_inset_(0) { | |
| 69 DCHECK_EQ(type_, COLOR_MATRIX); | |
| 70 memcpy(matrix_, matrix, sizeof(matrix_)); | |
| 71 } | |
| 72 | |
| 73 FilterOperation::FilterOperation(FilterType type, float amount, int inset) | |
| 74 : type_(type), | |
| 75 amount_(amount), | |
| 76 outer_threshold_(0), | |
| 77 drop_shadow_offset_(0, 0), | |
| 78 drop_shadow_color_(0), | |
| 79 zoom_inset_(inset) { | |
| 80 DCHECK_EQ(type_, ZOOM); | |
| 81 memset(matrix_, 0, sizeof(matrix_)); | |
| 82 } | |
| 83 | |
| 84 FilterOperation::FilterOperation( | |
| 85 FilterType type, | |
| 86 const skia::RefPtr<SkImageFilter>& image_filter) | |
| 87 : type_(type), | |
| 88 amount_(0), | |
| 89 outer_threshold_(0), | |
| 90 drop_shadow_offset_(0, 0), | |
| 91 drop_shadow_color_(0), | |
| 92 image_filter_(image_filter), | |
| 93 zoom_inset_(0) { | |
| 94 DCHECK_EQ(type_, REFERENCE); | |
| 95 memset(matrix_, 0, sizeof(matrix_)); | |
| 96 } | |
| 97 | |
| 98 FilterOperation::FilterOperation(FilterType type, | |
| 99 const SkRegion& region, | |
| 100 float inner_threshold, | |
| 101 float outer_threshold) | |
| 102 : type_(type), | |
| 103 amount_(inner_threshold), | |
| 104 outer_threshold_(outer_threshold), | |
| 105 drop_shadow_offset_(0, 0), | |
| 106 drop_shadow_color_(0), | |
| 107 zoom_inset_(0), | |
| 108 region_(region) { | |
| 109 DCHECK_EQ(type_, ALPHA_THRESHOLD); | |
| 110 memset(matrix_, 0, sizeof(matrix_)); | |
| 111 } | |
| 112 | |
| 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_)); | |
| 123 } | |
| 124 | |
| 125 FilterOperation::~FilterOperation() { | |
| 126 } | |
| 127 | |
| 128 static FilterOperation CreateNoOpFilter(FilterOperation::FilterType type) { | |
| 129 switch (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: { | |
| 152 SkScalar matrix[20]; | |
| 153 memset(matrix, 0, 20 * sizeof(SkScalar)); | |
| 154 matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1.f; | |
| 155 return FilterOperation::CreateColorMatrixFilter(matrix); | |
| 156 } | |
| 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); | |
| 166 } | |
| 167 NOTREACHED(); | |
| 168 return FilterOperation::CreateEmptyFilter(); | |
| 169 } | |
| 170 | |
| 171 static float ClampAmountForFilterType(float amount, | |
| 172 FilterOperation::FilterType type) { | |
| 173 switch (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: | |
| 190 return amount; | |
| 191 case FilterOperation::COLOR_MATRIX: | |
| 192 case FilterOperation::REFERENCE: | |
| 193 NOTREACHED(); | |
| 194 return amount; | |
| 195 } | |
| 196 NOTREACHED(); | |
| 197 return amount; | |
| 198 } | |
| 199 | |
| 200 // static | |
| 201 FilterOperation FilterOperation::Blend(const FilterOperation* from, | |
| 202 const FilterOperation* to, | |
| 203 double progress) { | |
| 204 FilterOperation blended_filter = FilterOperation::CreateEmptyFilter(); | |
| 205 | |
| 206 if (!from && !to) | |
| 207 return blended_filter; | |
| 208 | |
| 209 const FilterOperation& from_op = from ? *from : CreateNoOpFilter(to->type()); | |
| 210 const FilterOperation& to_op = to ? *to : CreateNoOpFilter(from->type()); | |
| 211 | |
| 212 if (from_op.type() != to_op.type()) | |
| 213 return blended_filter; | |
| 214 | |
| 215 DCHECK(to_op.type() != FilterOperation::COLOR_MATRIX); | |
| 216 blended_filter.set_type(to_op.type()); | |
| 217 | |
| 218 if (to_op.type() == FilterOperation::REFERENCE) { | |
| 219 if (progress > 0.5) | |
| 220 blended_filter.set_image_filter(to_op.image_filter()); | |
| 221 else | |
| 222 blended_filter.set_image_filter(from_op.image_filter()); | |
| 223 return blended_filter; | |
| 224 } | |
| 225 | |
| 226 blended_filter.set_amount(ClampAmountForFilterType( | |
| 227 gfx::Tween::FloatValueBetween(progress, from_op.amount(), to_op.amount()), | |
| 228 to_op.type())); | |
| 229 | |
| 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), | |
| 245 0)); | |
| 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()), | |
| 251 to_op.type())); | |
| 252 blended_filter.set_region(to_op.region()); | |
| 253 } | |
| 254 | |
| 255 return blended_filter; | |
| 256 } | |
| 257 | |
| 258 void FilterOperation::AsValueInto(base::trace_event::TracedValue* value) const { | |
| 259 value->SetInteger("type", type_); | |
| 260 switch (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_); | |
| 272 break; | |
| 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_); | |
| 277 break; | |
| 278 case FilterOperation::COLOR_MATRIX: { | |
| 279 value->BeginArray("matrix"); | |
| 280 for (size_t i = 0; i < arraysize(matrix_); ++i) | |
| 281 value->AppendDouble(matrix_[i]); | |
| 282 value->EndArray(); | |
| 283 break; | |
| 284 } | |
| 285 case FilterOperation::ZOOM: | |
| 286 value->SetDouble("amount", amount_); | |
| 287 value->SetDouble("inset", zoom_inset_); | |
| 288 break; | |
| 289 case FilterOperation::REFERENCE: { | |
| 290 int count_inputs = 0; | |
| 291 bool can_filter_image_gpu = false; | |
| 292 if (image_filter_) { | |
| 293 count_inputs = image_filter_->countInputs(); | |
| 294 can_filter_image_gpu = image_filter_->canFilterImageGPU(); | |
| 295 } | |
| 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); | |
| 299 break; | |
| 300 } | |
| 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()); | |
| 311 } | |
| 312 value->EndArray(); | |
| 313 } | |
| 314 break; | |
| 315 } | |
| 316 } | |
| 317 | |
| 318 } // namespace cc | |
| OLD | NEW |