| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/output/render_surface_filters.h" | 5 #include "cc/output/render_surface_filters.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "cc/output/filter_operation.h" |
| 11 #include "cc/output/filter_operations.h" |
| 10 #include "skia/ext/refptr.h" | 12 #include "skia/ext/refptr.h" |
| 11 #include "third_party/WebKit/public/platform/WebFilterOperation.h" | |
| 12 #include "third_party/WebKit/public/platform/WebFilterOperations.h" | |
| 13 #include "third_party/skia/include/core/SkCanvas.h" | 13 #include "third_party/skia/include/core/SkCanvas.h" |
| 14 #include "third_party/skia/include/effects/SkBlurImageFilter.h" | 14 #include "third_party/skia/include/effects/SkBlurImageFilter.h" |
| 15 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" | 15 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" |
| 16 #include "third_party/skia/include/effects/SkMagnifierImageFilter.h" | 16 #include "third_party/skia/include/effects/SkMagnifierImageFilter.h" |
| 17 #include "third_party/skia/include/gpu/SkGpuDevice.h" | 17 #include "third_party/skia/include/gpu/SkGpuDevice.h" |
| 18 #include "third_party/skia/include/gpu/SkGrPixelRef.h" | 18 #include "third_party/skia/include/gpu/SkGrPixelRef.h" |
| 19 #include "ui/gfx/size_f.h" | 19 #include "ui/gfx/size_f.h" |
| 20 | 20 |
| 21 namespace cc { | 21 namespace cc { |
| 22 | 22 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 return (max_value > 1.f) || (min_value < 0.f); | 177 return (max_value > 1.f) || (min_value < 0.f); |
| 178 } | 178 } |
| 179 | 179 |
| 180 bool MatrixNeedsClamping(SkScalar matrix[20]) { | 180 bool MatrixNeedsClamping(SkScalar matrix[20]) { |
| 181 return ComponentNeedsClamping(matrix) | 181 return ComponentNeedsClamping(matrix) |
| 182 || ComponentNeedsClamping(matrix+5) | 182 || ComponentNeedsClamping(matrix+5) |
| 183 || ComponentNeedsClamping(matrix+10) | 183 || ComponentNeedsClamping(matrix+10) |
| 184 || ComponentNeedsClamping(matrix+15); | 184 || ComponentNeedsClamping(matrix+15); |
| 185 } | 185 } |
| 186 | 186 |
| 187 bool GetColorMatrix(const WebKit::WebFilterOperation& op, SkScalar matrix[20]) { | 187 bool GetColorMatrix(const FilterOperation& op, SkScalar matrix[20]) { |
| 188 switch (op.type()) { | 188 switch (op.type()) { |
| 189 case WebKit::WebFilterOperation::FilterTypeBrightness: { | 189 case FilterOperation::FilterTypeBrightness: { |
| 190 GetBrightnessMatrix(op.amount(), matrix); | 190 GetBrightnessMatrix(op.amount(), matrix); |
| 191 return true; | 191 return true; |
| 192 } | 192 } |
| 193 case WebKit::WebFilterOperation::FilterTypeSaturatingBrightness: { | 193 case FilterOperation::FilterTypeSaturatingBrightness: { |
| 194 GetSaturatingBrightnessMatrix(op.amount(), matrix); | 194 GetSaturatingBrightnessMatrix(op.amount(), matrix); |
| 195 return true; | 195 return true; |
| 196 } | 196 } |
| 197 case WebKit::WebFilterOperation::FilterTypeContrast: { | 197 case FilterOperation::FilterTypeContrast: { |
| 198 GetContrastMatrix(op.amount(), matrix); | 198 GetContrastMatrix(op.amount(), matrix); |
| 199 return true; | 199 return true; |
| 200 } | 200 } |
| 201 case WebKit::WebFilterOperation::FilterTypeGrayscale: { | 201 case FilterOperation::FilterTypeGrayscale: { |
| 202 GetGrayscaleMatrix(1.f - op.amount(), matrix); | 202 GetGrayscaleMatrix(1.f - op.amount(), matrix); |
| 203 return true; | 203 return true; |
| 204 } | 204 } |
| 205 case WebKit::WebFilterOperation::FilterTypeSepia: { | 205 case FilterOperation::FilterTypeSepia: { |
| 206 GetSepiaMatrix(1.f - op.amount(), matrix); | 206 GetSepiaMatrix(1.f - op.amount(), matrix); |
| 207 return true; | 207 return true; |
| 208 } | 208 } |
| 209 case WebKit::WebFilterOperation::FilterTypeSaturate: { | 209 case FilterOperation::FilterTypeSaturate: { |
| 210 GetSaturateMatrix(op.amount(), matrix); | 210 GetSaturateMatrix(op.amount(), matrix); |
| 211 return true; | 211 return true; |
| 212 } | 212 } |
| 213 case WebKit::WebFilterOperation::FilterTypeHueRotate: { | 213 case FilterOperation::FilterTypeHueRotate: { |
| 214 GetHueRotateMatrix(op.amount(), matrix); | 214 GetHueRotateMatrix(op.amount(), matrix); |
| 215 return true; | 215 return true; |
| 216 } | 216 } |
| 217 case WebKit::WebFilterOperation::FilterTypeInvert: { | 217 case FilterOperation::FilterTypeInvert: { |
| 218 GetInvertMatrix(op.amount(), matrix); | 218 GetInvertMatrix(op.amount(), matrix); |
| 219 return true; | 219 return true; |
| 220 } | 220 } |
| 221 case WebKit::WebFilterOperation::FilterTypeOpacity: { | 221 case FilterOperation::FilterTypeOpacity: { |
| 222 GetOpacityMatrix(op.amount(), matrix); | 222 GetOpacityMatrix(op.amount(), matrix); |
| 223 return true; | 223 return true; |
| 224 } | 224 } |
| 225 case WebKit::WebFilterOperation::FilterTypeColorMatrix: { | 225 case FilterOperation::FilterTypeColorMatrix: { |
| 226 memcpy(matrix, op.matrix(), sizeof(SkScalar[20])); | 226 memcpy(matrix, op.matrix(), sizeof(SkScalar[20])); |
| 227 return true; | 227 return true; |
| 228 } | 228 } |
| 229 default: | 229 default: |
| 230 return false; | 230 return false; |
| 231 } | 231 } |
| 232 } | 232 } |
| 233 | 233 |
| 234 class FilterBufferState { | 234 class FilterBufferState { |
| 235 public: | 235 public: |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 GrContext* gr_context_; | 304 GrContext* gr_context_; |
| 305 SkBitmap source_; | 305 SkBitmap source_; |
| 306 skia::RefPtr<GrTexture> scratch_textures_[2]; | 306 skia::RefPtr<GrTexture> scratch_textures_[2]; |
| 307 int current_texture_; | 307 int current_texture_; |
| 308 skia::RefPtr<SkGpuDevice> device_; | 308 skia::RefPtr<SkGpuDevice> device_; |
| 309 skia::RefPtr<SkCanvas> canvas_; | 309 skia::RefPtr<SkCanvas> canvas_; |
| 310 }; | 310 }; |
| 311 | 311 |
| 312 } // namespace | 312 } // namespace |
| 313 | 313 |
| 314 WebKit::WebFilterOperations RenderSurfaceFilters::Optimize( | 314 FilterOperations RenderSurfaceFilters::Optimize( |
| 315 const WebKit::WebFilterOperations& filters) { | 315 const FilterOperations& filters) { |
| 316 WebKit::WebFilterOperations new_list; | 316 FilterOperations new_list; |
| 317 | 317 |
| 318 SkScalar accumulated_color_matrix[20]; | 318 SkScalar accumulated_color_matrix[20]; |
| 319 bool have_accumulated_color_matrix = false; | 319 bool have_accumulated_color_matrix = false; |
| 320 for (unsigned i = 0; i < filters.size(); ++i) { | 320 for (unsigned i = 0; i < filters.size(); ++i) { |
| 321 const WebKit::WebFilterOperation& op = filters.at(i); | 321 const FilterOperation& op = filters.at(i); |
| 322 | 322 |
| 323 // If the filter is a color matrix, we may be able to combine it with | 323 // If the filter is a color matrix, we may be able to combine it with |
| 324 // following Filter(s) that also are color matrices. | 324 // following Filter(s) that also are color matrices. |
| 325 SkScalar matrix[20]; | 325 SkScalar matrix[20]; |
| 326 if (GetColorMatrix(op, matrix)) { | 326 if (GetColorMatrix(op, matrix)) { |
| 327 if (have_accumulated_color_matrix) { | 327 if (have_accumulated_color_matrix) { |
| 328 SkScalar new_matrix[20]; | 328 SkScalar new_matrix[20]; |
| 329 MultColorMatrix(matrix, accumulated_color_matrix, new_matrix); | 329 MultColorMatrix(matrix, accumulated_color_matrix, new_matrix); |
| 330 memcpy(accumulated_color_matrix, | 330 memcpy(accumulated_color_matrix, |
| 331 new_matrix, | 331 new_matrix, |
| 332 sizeof(accumulated_color_matrix)); | 332 sizeof(accumulated_color_matrix)); |
| 333 } else { | 333 } else { |
| 334 memcpy(accumulated_color_matrix, | 334 memcpy(accumulated_color_matrix, |
| 335 matrix, | 335 matrix, |
| 336 sizeof(accumulated_color_matrix)); | 336 sizeof(accumulated_color_matrix)); |
| 337 have_accumulated_color_matrix = true; | 337 have_accumulated_color_matrix = true; |
| 338 } | 338 } |
| 339 | 339 |
| 340 // We can only combine matrices if clamping of color components | 340 // We can only combine matrices if clamping of color components |
| 341 // would have no effect. | 341 // would have no effect. |
| 342 if (!MatrixNeedsClamping(accumulated_color_matrix)) | 342 if (!MatrixNeedsClamping(accumulated_color_matrix)) |
| 343 continue; | 343 continue; |
| 344 } | 344 } |
| 345 | 345 |
| 346 if (have_accumulated_color_matrix) { | 346 if (have_accumulated_color_matrix) { |
| 347 new_list.append(WebKit::WebFilterOperation::createColorMatrixFilter( | 347 new_list.Append(FilterOperation::CreateColorMatrixFilter( |
| 348 accumulated_color_matrix)); | 348 accumulated_color_matrix)); |
| 349 } | 349 } |
| 350 have_accumulated_color_matrix = false; | 350 have_accumulated_color_matrix = false; |
| 351 | 351 |
| 352 switch (op.type()) { | 352 switch (op.type()) { |
| 353 case WebKit::WebFilterOperation::FilterTypeBlur: | 353 case FilterOperation::FilterTypeBlur: |
| 354 case WebKit::WebFilterOperation::FilterTypeDropShadow: | 354 case FilterOperation::FilterTypeDropShadow: |
| 355 case WebKit::WebFilterOperation::FilterTypeZoom: | 355 case FilterOperation::FilterTypeZoom: |
| 356 new_list.append(op); | 356 new_list.Append(op); |
| 357 break; | 357 break; |
| 358 case WebKit::WebFilterOperation::FilterTypeBrightness: | 358 case FilterOperation::FilterTypeBrightness: |
| 359 case WebKit::WebFilterOperation::FilterTypeSaturatingBrightness: | 359 case FilterOperation::FilterTypeSaturatingBrightness: |
| 360 case WebKit::WebFilterOperation::FilterTypeContrast: | 360 case FilterOperation::FilterTypeContrast: |
| 361 case WebKit::WebFilterOperation::FilterTypeGrayscale: | 361 case FilterOperation::FilterTypeGrayscale: |
| 362 case WebKit::WebFilterOperation::FilterTypeSepia: | 362 case FilterOperation::FilterTypeSepia: |
| 363 case WebKit::WebFilterOperation::FilterTypeSaturate: | 363 case FilterOperation::FilterTypeSaturate: |
| 364 case WebKit::WebFilterOperation::FilterTypeHueRotate: | 364 case FilterOperation::FilterTypeHueRotate: |
| 365 case WebKit::WebFilterOperation::FilterTypeInvert: | 365 case FilterOperation::FilterTypeInvert: |
| 366 case WebKit::WebFilterOperation::FilterTypeOpacity: | 366 case FilterOperation::FilterTypeOpacity: |
| 367 case WebKit::WebFilterOperation::FilterTypeColorMatrix: | 367 case FilterOperation::FilterTypeColorMatrix: |
| 368 break; | 368 break; |
| 369 } | 369 } |
| 370 } | 370 } |
| 371 if (have_accumulated_color_matrix) { | 371 if (have_accumulated_color_matrix) { |
| 372 new_list.append(WebKit::WebFilterOperation::createColorMatrixFilter( | 372 new_list.Append(FilterOperation::CreateColorMatrixFilter( |
| 373 accumulated_color_matrix)); | 373 accumulated_color_matrix)); |
| 374 } | 374 } |
| 375 return new_list; | 375 return new_list; |
| 376 } | 376 } |
| 377 | 377 |
| 378 SkBitmap RenderSurfaceFilters::Apply(const WebKit::WebFilterOperations& filters, | 378 SkBitmap RenderSurfaceFilters::Apply(const FilterOperations& filters, |
| 379 unsigned texture_id, | 379 unsigned texture_id, |
| 380 gfx::SizeF size, | 380 gfx::SizeF size, |
| 381 GrContext* gr_context) { | 381 GrContext* gr_context) { |
| 382 DCHECK(gr_context); | 382 DCHECK(gr_context); |
| 383 | 383 |
| 384 WebKit::WebFilterOperations optimized_filters = Optimize(filters); | 384 FilterOperations optimized_filters = Optimize(filters); |
| 385 FilterBufferState state(gr_context, size, texture_id); | 385 FilterBufferState state(gr_context, size, texture_id); |
| 386 if (!state.Init(optimized_filters.size())) | 386 if (!state.Init(optimized_filters.size())) |
| 387 return SkBitmap(); | 387 return SkBitmap(); |
| 388 | 388 |
| 389 for (unsigned i = 0; i < optimized_filters.size(); ++i) { | 389 for (unsigned i = 0; i < optimized_filters.size(); ++i) { |
| 390 const WebKit::WebFilterOperation& op = optimized_filters.at(i); | 390 const FilterOperation& op = optimized_filters.at(i); |
| 391 SkCanvas* canvas = state.Canvas(); | 391 SkCanvas* canvas = state.Canvas(); |
| 392 switch (op.type()) { | 392 switch (op.type()) { |
| 393 case WebKit::WebFilterOperation::FilterTypeColorMatrix: { | 393 case FilterOperation::FilterTypeColorMatrix: { |
| 394 SkPaint paint; | 394 SkPaint paint; |
| 395 skia::RefPtr<SkColorMatrixFilter> filter = | 395 skia::RefPtr<SkColorMatrixFilter> filter = |
| 396 skia::AdoptRef(new SkColorMatrixFilter(op.matrix())); | 396 skia::AdoptRef(new SkColorMatrixFilter(op.matrix())); |
| 397 paint.setColorFilter(filter.get()); | 397 paint.setColorFilter(filter.get()); |
| 398 canvas->drawBitmap(state.Source(), 0, 0, &paint); | 398 canvas->drawBitmap(state.Source(), 0, 0, &paint); |
| 399 break; | 399 break; |
| 400 } | 400 } |
| 401 case WebKit::WebFilterOperation::FilterTypeBlur: { | 401 case FilterOperation::FilterTypeBlur: { |
| 402 float std_deviation = op.amount(); | 402 float std_deviation = op.amount(); |
| 403 skia::RefPtr<SkImageFilter> filter = | 403 skia::RefPtr<SkImageFilter> filter = |
| 404 skia::AdoptRef(new SkBlurImageFilter(std_deviation, std_deviation)); | 404 skia::AdoptRef(new SkBlurImageFilter(std_deviation, std_deviation)); |
| 405 SkPaint paint; | 405 SkPaint paint; |
| 406 paint.setImageFilter(filter.get()); | 406 paint.setImageFilter(filter.get()); |
| 407 canvas->drawSprite(state.Source(), 0, 0, &paint); | 407 canvas->drawSprite(state.Source(), 0, 0, &paint); |
| 408 break; | 408 break; |
| 409 } | 409 } |
| 410 case WebKit::WebFilterOperation::FilterTypeDropShadow: { | 410 case FilterOperation::FilterTypeDropShadow: { |
| 411 skia::RefPtr<SkImageFilter> blur_filter = | 411 skia::RefPtr<SkImageFilter> blur_filter = |
| 412 skia::AdoptRef(new SkBlurImageFilter(op.amount(), op.amount())); | 412 skia::AdoptRef(new SkBlurImageFilter(op.amount(), op.amount())); |
| 413 skia::RefPtr<SkColorFilter> color_filter = | 413 skia::RefPtr<SkColorFilter> color_filter = |
| 414 skia::AdoptRef(SkColorFilter::CreateModeFilter( | 414 skia::AdoptRef(SkColorFilter::CreateModeFilter( |
| 415 op.dropShadowColor(), SkXfermode::kSrcIn_Mode)); | 415 op.drop_shadow_color(), SkXfermode::kSrcIn_Mode)); |
| 416 SkPaint paint; | 416 SkPaint paint; |
| 417 paint.setImageFilter(blur_filter.get()); | 417 paint.setImageFilter(blur_filter.get()); |
| 418 paint.setColorFilter(color_filter.get()); | 418 paint.setColorFilter(color_filter.get()); |
| 419 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); | 419 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); |
| 420 canvas->saveLayer(NULL, &paint); | 420 canvas->saveLayer(NULL, &paint); |
| 421 canvas->drawBitmap(state.Source(), | 421 canvas->drawBitmap(state.Source(), |
| 422 op.dropShadowOffset().x, | 422 op.drop_shadow_offset().x(), |
| 423 op.dropShadowOffset().y); | 423 op.drop_shadow_offset().y()); |
| 424 canvas->restore(); | 424 canvas->restore(); |
| 425 canvas->drawBitmap(state.Source(), 0, 0); | 425 canvas->drawBitmap(state.Source(), 0, 0); |
| 426 break; | 426 break; |
| 427 } | 427 } |
| 428 case WebKit::WebFilterOperation::FilterTypeZoom: { | 428 case FilterOperation::FilterTypeZoom: { |
| 429 SkPaint paint; | 429 SkPaint paint; |
| 430 int width = state.Source().width(); | 430 int width = state.Source().width(); |
| 431 int height = state.Source().height(); | 431 int height = state.Source().height(); |
| 432 skia::RefPtr<SkImageFilter> zoom_filter = skia::AdoptRef( | 432 skia::RefPtr<SkImageFilter> zoom_filter = skia::AdoptRef( |
| 433 new SkMagnifierImageFilter( | 433 new SkMagnifierImageFilter( |
| 434 SkRect::MakeXYWH( | 434 SkRect::MakeXYWH( |
| 435 (width - (width / op.amount())) / 2.f, | 435 (width - (width / op.amount())) / 2.f, |
| 436 (height - (height / op.amount())) / 2.f, | 436 (height - (height / op.amount())) / 2.f, |
| 437 width / op.amount(), | 437 width / op.amount(), |
| 438 height / op.amount()), | 438 height / op.amount()), |
| 439 op.zoomInset())); | 439 op.zoom_inset())); |
| 440 paint.setImageFilter(zoom_filter.get()); | 440 paint.setImageFilter(zoom_filter.get()); |
| 441 canvas->saveLayer(NULL, &paint); | 441 canvas->saveLayer(NULL, &paint); |
| 442 canvas->drawBitmap(state.Source(), 0, 0); | 442 canvas->drawBitmap(state.Source(), 0, 0); |
| 443 canvas->restore(); | 443 canvas->restore(); |
| 444 break; | 444 break; |
| 445 } | 445 } |
| 446 case WebKit::WebFilterOperation::FilterTypeBrightness: | 446 case FilterOperation::FilterTypeBrightness: |
| 447 case WebKit::WebFilterOperation::FilterTypeSaturatingBrightness: | 447 case FilterOperation::FilterTypeSaturatingBrightness: |
| 448 case WebKit::WebFilterOperation::FilterTypeContrast: | 448 case FilterOperation::FilterTypeContrast: |
| 449 case WebKit::WebFilterOperation::FilterTypeGrayscale: | 449 case FilterOperation::FilterTypeGrayscale: |
| 450 case WebKit::WebFilterOperation::FilterTypeSepia: | 450 case FilterOperation::FilterTypeSepia: |
| 451 case WebKit::WebFilterOperation::FilterTypeSaturate: | 451 case FilterOperation::FilterTypeSaturate: |
| 452 case WebKit::WebFilterOperation::FilterTypeHueRotate: | 452 case FilterOperation::FilterTypeHueRotate: |
| 453 case WebKit::WebFilterOperation::FilterTypeInvert: | 453 case FilterOperation::FilterTypeInvert: |
| 454 case WebKit::WebFilterOperation::FilterTypeOpacity: | 454 case FilterOperation::FilterTypeOpacity: |
| 455 NOTREACHED(); | 455 NOTREACHED(); |
| 456 break; | 456 break; |
| 457 } | 457 } |
| 458 state.Swap(); | 458 state.Swap(); |
| 459 } | 459 } |
| 460 return state.Source(); | 460 return state.Source(); |
| 461 } | 461 } |
| 462 | 462 |
| 463 } // namespace cc | 463 } // namespace cc |
| OLD | NEW |