| OLD | NEW |
| (Empty) |
| 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/render_surface_filters.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "skia/ext/refptr.h" | |
| 9 #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperation.
h" | |
| 10 #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperations
.h" | |
| 11 #include "third_party/skia/include/core/SkCanvas.h" | |
| 12 #include "third_party/skia/include/effects/SkBlurImageFilter.h" | |
| 13 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" | |
| 14 #include "third_party/skia/include/effects/SkMagnifierImageFilter.h" | |
| 15 #include "third_party/skia/include/gpu/SkGpuDevice.h" | |
| 16 #include "third_party/skia/include/gpu/SkGrPixelRef.h" | |
| 17 #include "ui/gfx/size_f.h" | |
| 18 | |
| 19 namespace cc { | |
| 20 | |
| 21 namespace { | |
| 22 | |
| 23 void GetBrightnessMatrix(float amount, SkScalar matrix[20]) { | |
| 24 // Spec implementation | |
| 25 // (http://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#brightnessEquiv
alent) | |
| 26 // <feFunc[R|G|B] type="linear" slope="[amount]"> | |
| 27 memset(matrix, 0, 20 * sizeof(SkScalar)); | |
| 28 matrix[0] = matrix[6] = matrix[12] = amount; | |
| 29 matrix[18] = 1.f; | |
| 30 } | |
| 31 | |
| 32 void GetSaturatingBrightnessMatrix(float amount, SkScalar matrix[20]) { | |
| 33 // Legacy implementation used by internal clients. | |
| 34 // <feFunc[R|G|B] type="linear" intercept="[amount]"/> | |
| 35 memset(matrix, 0, 20 * sizeof(SkScalar)); | |
| 36 matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1.f; | |
| 37 matrix[4] = matrix[9] = matrix[14] = amount * 255.f; | |
| 38 } | |
| 39 | |
| 40 void GetContrastMatrix(float amount, SkScalar matrix[20]) { | |
| 41 memset(matrix, 0, 20 * sizeof(SkScalar)); | |
| 42 matrix[0] = matrix[6] = matrix[12] = amount; | |
| 43 matrix[4] = matrix[9] = matrix[14] = (-0.5f * amount + 0.5f) * 255.f; | |
| 44 matrix[18] = 1.f; | |
| 45 } | |
| 46 | |
| 47 void GetSaturateMatrix(float amount, SkScalar matrix[20]) { | |
| 48 // Note, these values are computed to ensure matrixNeedsClamping is false | |
| 49 // for amount in [0..1] | |
| 50 matrix[0] = 0.213f + 0.787f * amount; | |
| 51 matrix[1] = 0.715f - 0.715f * amount; | |
| 52 matrix[2] = 1.f - (matrix[0] + matrix[1]); | |
| 53 matrix[3] = matrix[4] = 0.f; | |
| 54 matrix[5] = 0.213f - 0.213f * amount; | |
| 55 matrix[6] = 0.715f + 0.285f * amount; | |
| 56 matrix[7] = 1.f - (matrix[5] + matrix[6]); | |
| 57 matrix[8] = matrix[9] = 0.f; | |
| 58 matrix[10] = 0.213f - 0.213f * amount; | |
| 59 matrix[11] = 0.715f - 0.715f * amount; | |
| 60 matrix[12] = 1.f - (matrix[10] + matrix[11]); | |
| 61 matrix[13] = matrix[14] = 0.f; | |
| 62 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f; | |
| 63 matrix[18] = 1.f; | |
| 64 } | |
| 65 | |
| 66 void GetHueRotateMatrix(float hue, SkScalar matrix[20]) { | |
| 67 const float kPi = 3.1415926535897932384626433832795f; | |
| 68 | |
| 69 float cos_hue = cosf(hue * kPi / 180.f); | |
| 70 float sin_hue = sinf(hue * kPi / 180.f); | |
| 71 matrix[0] = 0.213f + cos_hue * 0.787f - sin_hue * 0.213f; | |
| 72 matrix[1] = 0.715f - cos_hue * 0.715f - sin_hue * 0.715f; | |
| 73 matrix[2] = 0.072f - cos_hue * 0.072f + sin_hue * 0.928f; | |
| 74 matrix[3] = matrix[4] = 0.f; | |
| 75 matrix[5] = 0.213f - cos_hue * 0.213f + sin_hue * 0.143f; | |
| 76 matrix[6] = 0.715f + cos_hue * 0.285f + sin_hue * 0.140f; | |
| 77 matrix[7] = 0.072f - cos_hue * 0.072f - sin_hue * 0.283f; | |
| 78 matrix[8] = matrix[9] = 0.f; | |
| 79 matrix[10] = 0.213f - cos_hue * 0.213f - sin_hue * 0.787f; | |
| 80 matrix[11] = 0.715f - cos_hue * 0.715f + sin_hue * 0.715f; | |
| 81 matrix[12] = 0.072f + cos_hue * 0.928f + sin_hue * 0.072f; | |
| 82 matrix[13] = matrix[14] = 0.f; | |
| 83 matrix[15] = matrix[16] = matrix[17] = 0.f; | |
| 84 matrix[18] = 1.f; | |
| 85 matrix[19] = 0.f; | |
| 86 } | |
| 87 | |
| 88 void GetInvertMatrix(float amount, SkScalar matrix[20]) { | |
| 89 memset(matrix, 0, 20 * sizeof(SkScalar)); | |
| 90 matrix[0] = matrix[6] = matrix[12] = 1.f - 2.f * amount; | |
| 91 matrix[4] = matrix[9] = matrix[14] = amount * 255.f; | |
| 92 matrix[18] = 1.f; | |
| 93 } | |
| 94 | |
| 95 void GetOpacityMatrix(float amount, SkScalar matrix[20]) { | |
| 96 memset(matrix, 0, 20 * sizeof(SkScalar)); | |
| 97 matrix[0] = matrix[6] = matrix[12] = 1.f; | |
| 98 matrix[18] = amount; | |
| 99 } | |
| 100 | |
| 101 void GetGrayscaleMatrix(float amount, SkScalar matrix[20]) { | |
| 102 // Note, these values are computed to ensure matrixNeedsClamping is false | |
| 103 // for amount in [0..1] | |
| 104 matrix[0] = 0.2126f + 0.7874f * amount; | |
| 105 matrix[1] = 0.7152f - 0.7152f * amount; | |
| 106 matrix[2] = 1.f - (matrix[0] + matrix[1]); | |
| 107 matrix[3] = matrix[4] = 0.f; | |
| 108 | |
| 109 matrix[5] = 0.2126f - 0.2126f * amount; | |
| 110 matrix[6] = 0.7152f + 0.2848f * amount; | |
| 111 matrix[7] = 1.f - (matrix[5] + matrix[6]); | |
| 112 matrix[8] = matrix[9] = 0.f; | |
| 113 | |
| 114 matrix[10] = 0.2126f - 0.2126f * amount; | |
| 115 matrix[11] = 0.7152f - 0.7152f * amount; | |
| 116 matrix[12] = 1.f - (matrix[10] + matrix[11]); | |
| 117 matrix[13] = matrix[14] = 0.f; | |
| 118 | |
| 119 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f; | |
| 120 matrix[18] = 1.f; | |
| 121 } | |
| 122 | |
| 123 void GetSepiaMatrix(float amount, SkScalar matrix[20]) { | |
| 124 matrix[0] = 0.393f + 0.607f * amount; | |
| 125 matrix[1] = 0.769f - 0.769f * amount; | |
| 126 matrix[2] = 0.189f - 0.189f * amount; | |
| 127 matrix[3] = matrix[4] = 0.f; | |
| 128 | |
| 129 matrix[5] = 0.349f - 0.349f * amount; | |
| 130 matrix[6] = 0.686f + 0.314f * amount; | |
| 131 matrix[7] = 0.168f - 0.168f * amount; | |
| 132 matrix[8] = matrix[9] = 0.f; | |
| 133 | |
| 134 matrix[10] = 0.272f - 0.272f * amount; | |
| 135 matrix[11] = 0.534f - 0.534f * amount; | |
| 136 matrix[12] = 0.131f + 0.869f * amount; | |
| 137 matrix[13] = matrix[14] = 0.f; | |
| 138 | |
| 139 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f; | |
| 140 matrix[18] = 1.f; | |
| 141 } | |
| 142 | |
| 143 // The 5x4 matrix is really a "compressed" version of a 5x5 matrix that'd have | |
| 144 // (0 0 0 0 1) as a last row, and that would be applied to a 5-vector extended | |
| 145 // from the 4-vector color with a 1. | |
| 146 void MultColorMatrix(SkScalar a[20], SkScalar b[20], SkScalar out[20]) { | |
| 147 for (int j = 0; j < 4; ++j) { | |
| 148 for (int i = 0; i < 5; ++i) { | |
| 149 out[i+j*5] = i == 4 ? a[4+j*5] : 0.f; | |
| 150 for (int k = 0; k < 4; ++k) | |
| 151 out[i+j*5] += a[k+j*5] * b[i+k*5]; | |
| 152 } | |
| 153 } | |
| 154 } | |
| 155 | |
| 156 // To detect if we need to apply clamping after applying a matrix, we check if | |
| 157 // any output component might go outside of [0, 255] for any combination of | |
| 158 // input components in [0..255]. | |
| 159 // Each output component is an affine transformation of the input component, so | |
| 160 // the minimum and maximum values are for any combination of minimum or maximum | |
| 161 // values of input components (i.e. 0 or 255). | |
| 162 // E.g. if R' = x*R + y*G + z*B + w*A + t | |
| 163 // Then the maximum value will be for R=255 if x>0 or R=0 if x<0, and the | |
| 164 // minimum value will be for R=0 if x>0 or R=255 if x<0. | |
| 165 // Same goes for all components. | |
| 166 bool ComponentNeedsClamping(SkScalar row[5]) { | |
| 167 SkScalar max_value = row[4] / 255.f; | |
| 168 SkScalar min_value = row[4] / 255.f; | |
| 169 for (int i = 0; i < 4; ++i) { | |
| 170 if (row[i] > 0) | |
| 171 max_value += row[i]; | |
| 172 else | |
| 173 min_value += row[i]; | |
| 174 } | |
| 175 return (max_value > 1.f) || (min_value < 0.f); | |
| 176 } | |
| 177 | |
| 178 bool MatrixNeedsClamping(SkScalar matrix[20]) { | |
| 179 return ComponentNeedsClamping(matrix) | |
| 180 || ComponentNeedsClamping(matrix+5) | |
| 181 || ComponentNeedsClamping(matrix+10) | |
| 182 || ComponentNeedsClamping(matrix+15); | |
| 183 } | |
| 184 | |
| 185 bool GetColorMatrix(const WebKit::WebFilterOperation& op, SkScalar matrix[20]) { | |
| 186 switch (op.type()) { | |
| 187 case WebKit::WebFilterOperation::FilterTypeBrightness: { | |
| 188 GetBrightnessMatrix(op.amount(), matrix); | |
| 189 return true; | |
| 190 } | |
| 191 case WebKit::WebFilterOperation::FilterTypeSaturatingBrightness: { | |
| 192 GetSaturatingBrightnessMatrix(op.amount(), matrix); | |
| 193 return true; | |
| 194 } | |
| 195 case WebKit::WebFilterOperation::FilterTypeContrast: { | |
| 196 GetContrastMatrix(op.amount(), matrix); | |
| 197 return true; | |
| 198 } | |
| 199 case WebKit::WebFilterOperation::FilterTypeGrayscale: { | |
| 200 GetGrayscaleMatrix(1.f - op.amount(), matrix); | |
| 201 return true; | |
| 202 } | |
| 203 case WebKit::WebFilterOperation::FilterTypeSepia: { | |
| 204 GetSepiaMatrix(1.f - op.amount(), matrix); | |
| 205 return true; | |
| 206 } | |
| 207 case WebKit::WebFilterOperation::FilterTypeSaturate: { | |
| 208 GetSaturateMatrix(op.amount(), matrix); | |
| 209 return true; | |
| 210 } | |
| 211 case WebKit::WebFilterOperation::FilterTypeHueRotate: { | |
| 212 GetHueRotateMatrix(op.amount(), matrix); | |
| 213 return true; | |
| 214 } | |
| 215 case WebKit::WebFilterOperation::FilterTypeInvert: { | |
| 216 GetInvertMatrix(op.amount(), matrix); | |
| 217 return true; | |
| 218 } | |
| 219 case WebKit::WebFilterOperation::FilterTypeOpacity: { | |
| 220 GetOpacityMatrix(op.amount(), matrix); | |
| 221 return true; | |
| 222 } | |
| 223 case WebKit::WebFilterOperation::FilterTypeColorMatrix: { | |
| 224 memcpy(matrix, op.matrix(), sizeof(SkScalar[20])); | |
| 225 return true; | |
| 226 } | |
| 227 default: | |
| 228 return false; | |
| 229 } | |
| 230 } | |
| 231 | |
| 232 class FilterBufferState { | |
| 233 public: | |
| 234 FilterBufferState(GrContext* gr_context, | |
| 235 gfx::SizeF size, | |
| 236 unsigned texture_id) | |
| 237 : gr_context_(gr_context), | |
| 238 current_texture_(0) { | |
| 239 // Wrap the source texture in a Ganesh platform texture. | |
| 240 GrBackendTextureDesc backend_texture_description; | |
| 241 backend_texture_description.fWidth = size.width(); | |
| 242 backend_texture_description.fHeight = size.height(); | |
| 243 backend_texture_description.fConfig = kSkia8888_GrPixelConfig; | |
| 244 backend_texture_description.fTextureHandle = texture_id; | |
| 245 skia::RefPtr<GrTexture> texture = skia::AdoptRef( | |
| 246 gr_context->wrapBackendTexture(backend_texture_description)); | |
| 247 // Place the platform texture inside an SkBitmap. | |
| 248 source_.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height()); | |
| 249 skia::RefPtr<SkGrPixelRef> pixel_ref = | |
| 250 skia::AdoptRef(new SkGrPixelRef(texture.get())); | |
| 251 source_.setPixelRef(pixel_ref.get()); | |
| 252 } | |
| 253 | |
| 254 ~FilterBufferState() {} | |
| 255 | |
| 256 bool Init(int filter_count) { | |
| 257 int scratch_count = std::min(2, filter_count); | |
| 258 GrTextureDesc desc; | |
| 259 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; | |
| 260 desc.fSampleCnt = 0; | |
| 261 desc.fWidth = source_.width(); | |
| 262 desc.fHeight = source_.height(); | |
| 263 desc.fConfig = kSkia8888_GrPixelConfig; | |
| 264 for (int i = 0; i < scratch_count; ++i) { | |
| 265 GrAutoScratchTexture scratch_texture( | |
| 266 gr_context_, desc, GrContext::kExact_ScratchTexMatch); | |
| 267 scratch_textures_[i] = skia::AdoptRef(scratch_texture.detach()); | |
| 268 if (!scratch_textures_[i]) | |
| 269 return false; | |
| 270 } | |
| 271 return true; | |
| 272 } | |
| 273 | |
| 274 SkCanvas* Canvas() { | |
| 275 if (!canvas_.get()) | |
| 276 CreateCanvas(); | |
| 277 return canvas_.get(); | |
| 278 } | |
| 279 | |
| 280 const SkBitmap& Source() { return source_; } | |
| 281 | |
| 282 void Swap() { | |
| 283 canvas_->flush(); | |
| 284 canvas_.clear(); | |
| 285 device_.clear(); | |
| 286 | |
| 287 skia::RefPtr<SkGrPixelRef> pixel_ref = skia::AdoptRef( | |
| 288 new SkGrPixelRef(scratch_textures_[current_texture_].get())); | |
| 289 source_.setPixelRef(pixel_ref.get()); | |
| 290 current_texture_ = 1 - current_texture_; | |
| 291 } | |
| 292 | |
| 293 private: | |
| 294 void CreateCanvas() { | |
| 295 DCHECK(scratch_textures_[current_texture_].get()); | |
| 296 device_ = skia::AdoptRef(new SkGpuDevice( | |
| 297 gr_context_, scratch_textures_[current_texture_].get())); | |
| 298 canvas_ = skia::AdoptRef(new SkCanvas(device_.get())); | |
| 299 canvas_->clear(0x0); | |
| 300 } | |
| 301 | |
| 302 GrContext* gr_context_; | |
| 303 SkBitmap source_; | |
| 304 skia::RefPtr<GrTexture> scratch_textures_[2]; | |
| 305 int current_texture_; | |
| 306 skia::RefPtr<SkGpuDevice> device_; | |
| 307 skia::RefPtr<SkCanvas> canvas_; | |
| 308 }; | |
| 309 | |
| 310 } // namespace | |
| 311 | |
| 312 WebKit::WebFilterOperations RenderSurfaceFilters::Optimize( | |
| 313 const WebKit::WebFilterOperations& filters) { | |
| 314 WebKit::WebFilterOperations new_list; | |
| 315 | |
| 316 SkScalar accumulated_color_matrix[20]; | |
| 317 bool have_accumulated_color_matrix = false; | |
| 318 for (unsigned i = 0; i < filters.size(); ++i) { | |
| 319 const WebKit::WebFilterOperation& op = filters.at(i); | |
| 320 | |
| 321 // If the filter is a color matrix, we may be able to combine it with | |
| 322 // following Filter(s) that also are color matrices. | |
| 323 SkScalar matrix[20]; | |
| 324 if (GetColorMatrix(op, matrix)) { | |
| 325 if (have_accumulated_color_matrix) { | |
| 326 SkScalar newMatrix[20]; | |
| 327 MultColorMatrix(matrix, accumulated_color_matrix, newMatrix); | |
| 328 memcpy(accumulated_color_matrix, | |
| 329 newMatrix, | |
| 330 sizeof(accumulated_color_matrix)); | |
| 331 } else { | |
| 332 memcpy(accumulated_color_matrix, | |
| 333 matrix, | |
| 334 sizeof(accumulated_color_matrix)); | |
| 335 have_accumulated_color_matrix = true; | |
| 336 } | |
| 337 | |
| 338 // We can only combine matrices if clamping of color components | |
| 339 // would have no effect. | |
| 340 if (!MatrixNeedsClamping(accumulated_color_matrix)) | |
| 341 continue; | |
| 342 } | |
| 343 | |
| 344 if (have_accumulated_color_matrix) { | |
| 345 new_list.append(WebKit::WebFilterOperation::createColorMatrixFilter( | |
| 346 accumulated_color_matrix)); | |
| 347 } | |
| 348 have_accumulated_color_matrix = false; | |
| 349 | |
| 350 switch (op.type()) { | |
| 351 case WebKit::WebFilterOperation::FilterTypeBlur: | |
| 352 case WebKit::WebFilterOperation::FilterTypeDropShadow: | |
| 353 case WebKit::WebFilterOperation::FilterTypeZoom: | |
| 354 new_list.append(op); | |
| 355 break; | |
| 356 case WebKit::WebFilterOperation::FilterTypeBrightness: | |
| 357 case WebKit::WebFilterOperation::FilterTypeSaturatingBrightness: | |
| 358 case WebKit::WebFilterOperation::FilterTypeContrast: | |
| 359 case WebKit::WebFilterOperation::FilterTypeGrayscale: | |
| 360 case WebKit::WebFilterOperation::FilterTypeSepia: | |
| 361 case WebKit::WebFilterOperation::FilterTypeSaturate: | |
| 362 case WebKit::WebFilterOperation::FilterTypeHueRotate: | |
| 363 case WebKit::WebFilterOperation::FilterTypeInvert: | |
| 364 case WebKit::WebFilterOperation::FilterTypeOpacity: | |
| 365 case WebKit::WebFilterOperation::FilterTypeColorMatrix: | |
| 366 break; | |
| 367 } | |
| 368 } | |
| 369 if (have_accumulated_color_matrix) { | |
| 370 new_list.append(WebKit::WebFilterOperation::createColorMatrixFilter( | |
| 371 accumulated_color_matrix)); | |
| 372 } | |
| 373 return new_list; | |
| 374 } | |
| 375 | |
| 376 SkBitmap RenderSurfaceFilters::Apply(const WebKit::WebFilterOperations& filters, | |
| 377 unsigned texture_id, | |
| 378 gfx::SizeF size, | |
| 379 GrContext* gr_context) { | |
| 380 DCHECK(gr_context); | |
| 381 | |
| 382 WebKit::WebFilterOperations optimized_filters = Optimize(filters); | |
| 383 FilterBufferState state(gr_context, size, texture_id); | |
| 384 if (!state.Init(optimized_filters.size())) | |
| 385 return SkBitmap(); | |
| 386 | |
| 387 for (unsigned i = 0; i < optimized_filters.size(); ++i) { | |
| 388 const WebKit::WebFilterOperation& op = optimized_filters.at(i); | |
| 389 SkCanvas* canvas = state.Canvas(); | |
| 390 switch (op.type()) { | |
| 391 case WebKit::WebFilterOperation::FilterTypeColorMatrix: { | |
| 392 SkPaint paint; | |
| 393 skia::RefPtr<SkColorMatrixFilter> filter = | |
| 394 skia::AdoptRef(new SkColorMatrixFilter(op.matrix())); | |
| 395 paint.setColorFilter(filter.get()); | |
| 396 canvas->drawBitmap(state.Source(), 0, 0, &paint); | |
| 397 break; | |
| 398 } | |
| 399 case WebKit::WebFilterOperation::FilterTypeBlur: { | |
| 400 float std_deviation = op.amount(); | |
| 401 skia::RefPtr<SkImageFilter> filter = | |
| 402 skia::AdoptRef(new SkBlurImageFilter(std_deviation, std_deviation)); | |
| 403 SkPaint paint; | |
| 404 paint.setImageFilter(filter.get()); | |
| 405 canvas->drawSprite(state.Source(), 0, 0, &paint); | |
| 406 break; | |
| 407 } | |
| 408 case WebKit::WebFilterOperation::FilterTypeDropShadow: { | |
| 409 skia::RefPtr<SkImageFilter> blur_filter = | |
| 410 skia::AdoptRef(new SkBlurImageFilter(op.amount(), op.amount())); | |
| 411 skia::RefPtr<SkColorFilter> color_filter = | |
| 412 skia::AdoptRef(SkColorFilter::CreateModeFilter( | |
| 413 op.dropShadowColor(), SkXfermode::kSrcIn_Mode)); | |
| 414 SkPaint paint; | |
| 415 paint.setImageFilter(blur_filter.get()); | |
| 416 paint.setColorFilter(color_filter.get()); | |
| 417 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); | |
| 418 canvas->saveLayer(NULL, &paint); | |
| 419 canvas->drawBitmap(state.Source(), | |
| 420 op.dropShadowOffset().x, | |
| 421 -op.dropShadowOffset().y); | |
| 422 canvas->restore(); | |
| 423 canvas->drawBitmap(state.Source(), 0, 0); | |
| 424 break; | |
| 425 } | |
| 426 case WebKit::WebFilterOperation::FilterTypeZoom: { | |
| 427 SkPaint paint; | |
| 428 int width = state.Source().width(); | |
| 429 int height = state.Source().height(); | |
| 430 skia::RefPtr<SkImageFilter> zoom_filter = skia::AdoptRef( | |
| 431 new SkMagnifierImageFilter( | |
| 432 SkRect::MakeXYWH( | |
| 433 (width - (width / op.amount())) / 2.f, | |
| 434 (height - (height / op.amount())) / 2.f, | |
| 435 width / op.amount(), | |
| 436 height / op.amount()), | |
| 437 op.zoomInset())); | |
| 438 paint.setImageFilter(zoom_filter.get()); | |
| 439 canvas->saveLayer(NULL, &paint); | |
| 440 canvas->drawBitmap(state.Source(), 0, 0); | |
| 441 canvas->restore(); | |
| 442 break; | |
| 443 } | |
| 444 case WebKit::WebFilterOperation::FilterTypeBrightness: | |
| 445 case WebKit::WebFilterOperation::FilterTypeSaturatingBrightness: | |
| 446 case WebKit::WebFilterOperation::FilterTypeContrast: | |
| 447 case WebKit::WebFilterOperation::FilterTypeGrayscale: | |
| 448 case WebKit::WebFilterOperation::FilterTypeSepia: | |
| 449 case WebKit::WebFilterOperation::FilterTypeSaturate: | |
| 450 case WebKit::WebFilterOperation::FilterTypeHueRotate: | |
| 451 case WebKit::WebFilterOperation::FilterTypeInvert: | |
| 452 case WebKit::WebFilterOperation::FilterTypeOpacity: | |
| 453 NOTREACHED(); | |
| 454 break; | |
| 455 } | |
| 456 state.Swap(); | |
| 457 } | |
| 458 return state.Source(); | |
| 459 } | |
| 460 | |
| 461 } // namespace cc | |
| OLD | NEW |